我有一个网页,其中包含产品下拉列表和两组过滤器:类型(教育,游戏)和媒体(书籍,CD)。您可以随时从任一过滤器中进行选择,并通过ajax相应地过滤下拉列表。这一切都很有效。
当您选择过滤器时,会在下拉列表上显示跳动,直到ajax结算。问题是,如果在完成解析之前多次更改过滤器,则第一个请求将删除throbber并在第二个请求仍在进行时再次显示下拉列表。这是一个我想解决的小问题。这是javascript:
$('.radio-filter-type').change(function() {
$("#products-list").hide();
$("#products-throbber").show();
$("#products-container").load(window.location + ' #products-list',
$("#filter-type").serialize() + '&medium=' + $("#filter-media
input[name=medium]:checked").val()
, function () {
$("#products-list").show();
$("#products-throbber").hide();
}
);
});
显然,单选按钮会在此期间发生变化,第一个.load()
会解析,显示列表并在另一个完成之前隐藏响尾蛇。我可以这样做:
reqCount = 0;
...
.change( ...
reqCount++;
.load( ...
, function () {
reqCount--;
if (!reqCount) { //show list and hide throbber
然而,对于Deferred
,我觉得必须有一个更清洁的方式。有没有办法将请求添加到当前的Deffered堆栈并等待它们全部解析(它们可以在任意时间添加)。我还注意到.load().then()
似乎不起作用。可以Deferred
与.load()
一起使用吗?我使用.load()
因为您可以指定仅返回的DOM元素,这很方便。如果没有,是否还有其他方法来管理当前的ajax请求并仅在它们全部完成时才执行操作?
答案 0 :(得分:0)
为什么不在ajax帖子正在进行时禁用过滤器输入?不太好,但解决了你的问题。
$('.radio-filter-type').change(function() {
$("#products-list").hide();
$("#products-throbber").show();
//disable checkbox
$("#filter-media input[name=medium]).attr('disabled', 'disabled');
$("#products-container").load(window.location + ' #products-list',
$("#filter-type").serialize() + '&medium=' + $("#filter-media
input[name=medium]:checked").val()
, function () {
$("#products-list").show();
$("#products-throbber").hide();
//renable checkbox
$("#filter-media input[name=medium]).removeAttr('disabled');
}
);
});
答案 1 :(得分:0)
执行此操作的方法是,如果过滤器的值与原始请求的值不同,则取消成功结束ajax请求时的操作。这是对代码可能是什么样子的尝试:
$('.radio-filter-type').change(function() {
var filterStateAtChange = $("#filter-media input[name=medium]).is(':checked');
$("#products-list").hide();
$("#products-throbber").show();
$.get(window.location + ' #products-list',
$("#filter-type").serialize() + '&medium=' + $("#filter-media
input[name=medium]:checked").val()
,
function (html) {
//cancel (do nothing) if the value of the checkbox now is not equal to what it was when request originated
if (filterStateAtChange === $("#filter-media input[name=medium]).is(':checked')) {
$("#products-container").html(html)
$("#products-list").show();
$("#products-throbber").hide();
}
}
);
});