0

jQuery.post()にいくつかの追加機能を提供したいと思います。サーバーからの応答を確認し、さまざまなコールバックを呼び出せるようにしたい。

例えば:

$("#frmFoo").postForm("ajax")
    .start(function () { showSpinner(); })
    .success(function () { alert ("Foo saved"); })
    .error(function() { alert ("Foo could not be saved at this time"); })
    .validationError(function() { alert("Please fix foo and try again"); })
    .complete(function() { hideSpinner(); });

そのため、一貫性のあるJSONオブジェクトをページに送り返し、そのJSONオブジェクトに基づいてsuccessまたはvalidationErrorを呼び出し、validationErrorに追加情報を提供できるようにしたいと考えています。

更新 それは急な学習曲線であり、私は何か間違ったことをしたとほぼ100%確信しています。以下は、私が望んでいた機能の試みです。

(function ($) {
     $.fn.postForm = function (url) {
         var options = options || {};
         var formData = this.serialize();
         var validationCb = jQuery.Callbacks("once memory");
         var successCb = jQuery.Callbacks("once memory");
         var errorCb = jQuery.Callbacks("once memory");
         var completeCb = jQuery.Callbacks("once memory");
         var s = jQuery.ajaxSetup({ }, options);
         var callbackContext = s.context || s;
         foo = {
             success: function () {
                 successCb.add(arguments[0]);
                 return this;
            },
             complete: function() {
                 completeCb.add(arguments[0]);
                 return this;
            },
            validationError : function() {
                validationCb.add(arguments[0]);
                return this;
            },
            error: function() {
                errorCb.add(arguments[0]);
                return this;
            }
         };
         $.post(url, formData)
            .success(function(data, textStatus, jqXhr) {
                 if (!data.Success) {
                     validationCb.fireWith(callbackContext, [data.Message, data.KeyValuePairs]);
                 } else {
                     successCb.fireWith(callbackContext, [data, textStatus, jqXhr]);
                 }
            })
            .complete(function (jqXhr, textStatus) {
                completeCb.fireWith(callbackContext, [jqXhr, textStatus]);
            })
            .error(function(jqXhr, textStatus, errorThrown) {
                errorCb.fireWith(callbackContext, [jqXhr, textStatus, errorThrown]);
            });
         return foo;
     };
 })(jQuery);

それで、私がしたことはどれほど悪いですか?私はjavascriptとjQueryに精通しておらず、私を噛むことになっているいくつかのルールを破っていると確信しています。

4

3 に答える 3

1

promiseインターフェースを効果的に変更するため、提案していることを実行することはあまり実用的ではありません。

$.postの結果を呼び出し元に返すだけで、必要なものの多くがすでに存在していることに注意してください。

showSpinner();
$.post({...})
    .done(...)           // aka .success (deprecated)
    .fail(...)           // aka .error (deprecated)
    .always(stopSpinner) // aka .complete (deprecated)

したがって、最初にスピナーを表示する必要がありますが、それはほとんど困難ではなく、検証エラーをキャッチする方法がないため、.done関数の一部である必要があります。

于 2012-11-16T13:48:17.920 に答える
0

私があなたが達成したいことを正しく理解しているなら、あなたは$ .ajax()を使うべきです。

$.ajax({
  url: your_url,
  type: 'POST'
  beforeSend: function(){ showSpinner(); },
  error: function() { alert ("Foo could not be saved at this time"); }
  success: function (data) { 
     if (data.validation == true) { //example of validation, depends on how you send data from backend
       alert ("Foo saved");
       hideSpinner();
     } else {
        alert("Please fix " + data.foo + " and try again"); //again depends on how you send data     
     }
  }
于 2012-11-16T13:35:50.627 に答える
0

$ .Deferred(または本当にカスタムなものが必要な場合は$ .Callbacks)、またはより一般的にはpromiseパターンを探しています。単純な実装は次のようになります。

(function ($) {
    $.fn.postForm = function (url, options) {
        var options = options || {},
            s = jQuery.ajaxSetup({ }, options),
            callbackContext = s.context || s;

        var formData = this.serialize();
        var post = $.post(url, formData);
        var deferred = post.pipe(function(data, textStatus, jqXhr) {
            if (!data.Success) {
                // HTTP OK, soft error
                return $.Deferred().rejectWith(callbackContext, [data.Message, data.KeyValuePairs]);
            } else {
                // success
                return $.Deferred().resolveWith(callbackContext, [data, textStatus, jqXhr]);
            }
        }, function(jqXhr, textStatus, errorThrown) {
            // HTTP error
            return $.Deferred().rejectWith(callbackContext, [errorThrown, {}]);
        });

        deferred.success = deferred.done;
        deferred.error = deferred.fail;
        deferred.complete = deferred.always;

        return deferred;
    };
})(jQuery);

errorこれは/を区別しませんvalidationErrorが、ほとんどのバイオラープレートコードを取り除きます。

于 2012-11-20T14:43:47.533 に答える