0

我有一个带有产品下拉列表和两组过滤器的网页:类型(教育、游戏)和媒体(书籍、CD)。您可以随时从任一过滤器中进行选择,下拉菜单将通过 ajax 进行相应的过滤。这一切都很好。

当您选择一个过滤器时,一个 throbber 会显示在下拉列表中,直到 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()将在另一个完成之前解析、显示列表并隐藏 throbber。我可以做这样的事情:

reqCount = 0;
...
.change( ...
   reqCount++;
   .load( ...
      , function () {
         reqCount--;
         if (!reqCount) { //show list and hide throbber

但是,Deferred我觉得必须有一种更清洁的方式。有没有办法将请求添加到当前的延迟堆栈并等待它们全部解决(它们可以在任意时间添加)。我也注意到这.load().then()似乎不起作用。完全可以Deferred.load()吗?我使用.load()是因为你可以指定只返回的 DOM 元素,这很方便。如果没有,是否有任何其他方法来管理当前的 ajax 请求并仅在它们一次全部完成时才执行操作?

4

2 回答 2

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();
          }

       }
    );
 });
于 2011-11-23T21:37:29.987 回答
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');
       }
    );
 });
于 2011-11-23T21:29:58.040 回答