[英]How do I let someone chain callback methods on my jQuery plugin?
我想為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對象調用成功或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不熟悉,並且我確定自己違反了一些必定會咬我的規則。
按照您的建議進行操作不是很實際,因為它會有效地更改promise
接口。
請注意,如果您只是將$.post
的結果返回給調用者,則您想要的大部分已經存在:
showSpinner();
$.post({...})
.done(...) // aka .success (deprecated)
.fail(...) // aka .error (deprecated)
.always(stopSpinner) // aka .complete (deprecated)
因此,您必須先顯示微調器,但這幾乎沒有什么困難,並且沒有辦法捕獲驗證錯誤,因此這需要成為您.done
函數的一部分。
如果我正確理解您要實現的目標,則應使用$ .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
}
}
您正在尋找$ .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
,但是擺脫了大部分biolerplate代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.