2010-07-14 4 views
0

Я написал код, который фильтрует в провинции/штат выберите поле после того, как вы выбираете страну:Как избежать 3 вызовов ajax?

var cache = {}; 

    function updateProvinceOptions($select, values, initial) { 
      for(i in values) { 
        $select.append('<option value="'+values[i][0]+'">'+values[i][1]+'</option>'); 
      } 
      $select.val(initial).trigger('change'); 
    } 

    $('<select class="province" />').insertBefore('.province').change(function() { // insert select boxes beside hidden province inputs 
      $(this).siblings('input.province').val($(this).val()); // update hidden input with current value 
    }); 

    $('.country').change(function() { 
      var $countrySel = $(this); 
      var $provSel = $countrySel.parent().parent().next().children('td').children('select.province'); 
      var $provInput = $provSel.siblings('input.province'); 
      var country = $countrySel.val(); 
      var province = $provInput.val(); 

      $provSel.empty(); 
      if(country in cache) { 
        updateProvinceOptions($provSel, cache[country], province); 
      } 
      else { 
        $provSel.addClass('loading'); 
        $.getJSON('/get-provinces.json', {'country':country}, function(provinces) { 
          $provSel.removeClass('loading'); 
          cache[country] = provinces; 
          updateProvinceOptions($provSel, provinces, province); 
        }); 
      } 
    }).trigger('change'); 

Он даже кэширует результаты, так что если вы, скажем, выбрать Канаду, затем в США, а затем Канада снова, он не должен ударять по серверу для списка провинций Канады во второй раз. Тем не менее, я показываю 3 из них на странице в то же время. Когда страница сначала загружается, в кеше нет ничего, поэтому все 3 из них попадают на сервер для списка провинций, потому что ни один из вызовов ajax еще не вернулся.

Есть ли относительно простой способ сказать «ожидание», если вызов ajax для этой страны уже выполняется? Или мне даже надоело?

ответ

1

Nevermind .. ответил на свой вопрос еще раз, когда в ответ на спинонных ... это было не так трудно добавить «ожидание» очереди после того, как все:

var cache = {}; 
    var retrieving = {}; 

    function updateProvinceOptions($select, values, initial) { 
      for(i in values) { 
        $select.append('<option value="'+values[i][0]+'">'+values[i][1]+'</option>'); 
      } 
      $select.val(initial).trigger('change'); 
    } 

    $('<select class="province" />').insertBefore('.province').change(function() { // insert select boxes beside hidden province inputs 
      $(this).siblings('input.province').val($(this).val()); // update hidden input with current value 
    }); 

    $('.country').change(function() { 
      var $countrySel = $(this); 
      var $provSel = $countrySel.closest('tr').next('tr').find('select.province'); 
      var $provInput = $provSel.siblings('input.province'); 
      var country = $countrySel.val(); 
      var province = $provInput.val(); 

      $provSel.empty(); 
      if(country in cache) { 
        updateProvinceOptions($provSel, cache[country], province); 
      } else if(country in retrieving) { 
        retrieving[country].push($provSel); 
      } 
      else { 
        retrieving[country] = [$provSel] 
        $provSel.addClass('loading'); 
        $.getJSON('/get-provinces.json', {'country':country}, function(provinces) { 
          $provSel.removeClass('loading'); 
          cache[country] = provinces; 
          while(retrieving[country].length > 0) { 
            $select = retrieving[country].pop(); 
            updateProvinceOptions($select, provinces, province);  
          }        
        }); 
      } 
    }).trigger('change'); 
2

Я бы сказал, может быть, добавить свойство кэш-памяти или какой-либо другой объект вне вашего метода, чтобы указать, загружается ли кэш в настоящий момент. Перед вызовом метода ajax установите значение true, а затем установите значение false в функцию успеха вызова ajax после его завершения. Если это так, вы пропустите любые последующие вызовы, пока это значение не станет ложным.

Только одно возможное решение.

+0

Да, истинная/ложная часть - это легкий бит (определяющий, были ли данные уже запрошены) ... но как вы вставляете задержку? Я предполагаю, что вы добавили очередь «waitingOn» ... и когда полный метод ajax срабатывает, вы перебираете всех официантов. – mpen

+0

Похоже, вы поняли, что все вышло. Рад, что я мог бы помочь, если бы я вообще это сделал. Похоже, вы сами разобрались. Просто нужен маленький указатель. – spinon

0

Я бы сказал, что это зависит от варианта использования. Всегда ли пользователю проходить эти элементы? Если это так, я могу склониться к захвату всех данных, когда страница загружает или даже отправляет данные вниз со страницей в первую очередь.

Также зависит от количества предметов, с которыми вы имеете дело, возможно, автозаполнение было бы лучшим решением.

бы действительно нужно лучше почувствовать приложение посоветовать более сильно

+0

Ну, я не хочу захватывать все данные для всех стран .. это [может быть] много данных ... по умолчанию Канада, которая является нашей целевой аудиторией ... если они никогда не переключают страну , то остальные данные страны * никогда не должны загружаться. Идти на использование этого же скрипта для еще большего списка (фильтрует тысячи элементов). Автозаполнение не очень подходит, так как результирующие списки будут по-прежнему относительно небольшими (менее 50 вариантов). – mpen

+0

«Пройти»? Да, он всегда должен выбрать провинцию/государство. (Если значение по умолчанию не было правильно случайно) – mpen

Смежные вопросы