所以,我有一个加载的页面,并通过jquery.get生成几个请求,用它们的值填充下拉列表。
$(function() {
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
LoadContact();
};
然后调用LoadContact();这是另一个调用,当它返回时,它会填充表单上的所有字段。问题是通常情况下,下拉列表并非全部填充,因此无法将它们设置为正确的值。
我需要做的是,只有在其他方法完成并且回调完成执行后,LoadContact才会执行。
但是,我不想在下拉填充回调的末尾放置一堆标志,然后检查,并且在调用LoadContact()之前必须进行递归的setTimeout调用检查;
jQuery中是否有一些东西可以让我说:“完成所有这些后,执行它。”?
更多信息 我正在思考这些问题
$().executeAfter(
function () { // When these are done
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
},
LoadContact // Do this
);
...它需要跟踪在执行方法期间发生的ajax调用,并且当它们全部完成时,调用LoadContact;
如果我知道如何拦截在该函数中创建的ajax,我可能会编写一个jQuery扩展来执行此操作。
我的解决方案
;(function($) {
$.fn.executeAfter = function(methods, callback) {
var stack = [];
var trackAjaxSend = function(event, XMLHttpRequest, ajaxOptions) {
var url = ajaxOptions.url;
stack.push(url);
}
var trackAjaxComplete = function(event, XMLHttpRequest, ajaxOptions) {
var url = ajaxOptions.url;
var index = jQuery.inArray(url, stack);
if (index >= 0) {
stack.splice(index, 1);
}
if (stack.length == 0) {
callback();
$this.unbind("ajaxComplete");
}
}
var $this = $(this);
$this.ajaxSend(trackAjaxSend)
$this.ajaxComplete(trackAjaxComplete)
methods();
$this.unbind("ajaxSend");
};
})(jQuery);
这会在调用方法时绑定到ajaxSend事件,并保留一个调用的URL列表(需要更好的唯一ID )。然后它从ajaxSend解除绑定,因此只跟踪我们关心的请求。它还绑定到ajaxComplete并在返回时从堆栈中删除项目。当堆栈达到零时,它会执行我们的回调,并取消绑定ajaxComplete事件。
答案 0 :(得分:43)
您可以像这样使用.ajaxStop()
:
$(function() {
$(document).ajaxStop(function() {
$(this).unbind("ajaxStop"); //prevent running again when other calls finish
LoadContact();
});
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
});
这将在所有当前请求完成后运行,然后取消绑定,以便在页面执行中未来的ajax调用时不会运行。另外,请务必将其放在ajax调用之前,这样它就会被早期限制,对.ajaxStart()
更为重要,但最好的做法是同时使用它们。
答案 1 :(得分:17)
展开Tom Lianza's answer,$.when()
现在是比使用.ajaxStop()
更好的方法。
唯一需要注意的是,您需要确保在返回Deferred object
时需要等待的异步方法。幸运的是,jQuery ajax调用默认情况下已经这样做了。因此,要从问题中实现场景,需要等待的方法看起来像这样:
function LoadCategories(argument){
var deferred = $.ajax({
// ajax setup
}).then(function(response){
// optional callback to handle this response
});
return deferred;
}
然后在所有三个ajax调用返回后调用LoadContact()并可选地执行它们各自的回调:
// setting variables to emphasize that the functions must return deferred objects
var deferred1 = LoadCategories($('#Category'));
var deferred2 = LoadPositions($('#Position'));
var deferred3 = LoadDepartments($('#Department'));
$.when(deferred1, deferred2, deferred3).then(LoadContact);
答案 2 :(得分:7)
如果您使用的是Jquery 1.5或更高版本,我怀疑Deferred对象是您最好的选择: http://api.jquery.com/category/deferred-object/
辅助方法的时候,也很不错: http://api.jquery.com/jQuery.when/
答案 3 :(得分:0)
但是,我不想在下拉填充回调的最后放置一堆标志,然后检查,并且在调用LoadContact之前必须进行递归的setTimeout调用检查();
不需要setTimeout。您只需检入每个回调函数,即填充所有三个列表(或者更好地设置计数器,在每个回调中增加它并等待它等于3)然后从回调中调用LoadContact。对我来说似乎很容易。
ajaxStop方法可能有用,我只是不太熟悉它。