откладывание с помощью `.load ()` и / или стека ajax - PullRequest
0 голосов
/ 24 ноября 2011

У меня есть веб-страница с выпадающим списком товаров и двумя группами фильтров: Тип (образование, игры) и Медиа (книга, компакт-диск).Вы можете выбрать любой из фильтров в любое время, и выпадающий список будет отфильтрован соответственно через ajax.Все это прекрасно работает.

Когда вы выбираете фильтр, над выпадающим меню отображается пульсатор, пока не разрешится ajax.Проблема заключается в том, что если вы измените фильтр более одного раза до того, как он завершит разрешение, первый запрос удалит пульсатор и снова отобразит раскрывающийся список, пока второй запрос все еще выполняется.Это небольшая проблема, которую я хотел бы исправить.Вот 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 и выполнения действий только тогда, когда все они выполнены одновременно?

Ответы [ 2 ]

0 голосов
/ 24 ноября 2011

Способ сделать это - отменить действия при успешном завершении запроса 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();
          }

       }
    );
 });
0 голосов
/ 24 ноября 2011

Почему бы просто не отключить входные данные фильтра во время выполнения сообщения 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');
       }
    );
 });
...