Как избежать 3-х вызовов ajax? - PullRequest
0 голосов
/ 15 июля 2010

Я написал код, который фильтрует поле выбора провинции / штата после выбора страны:

    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 для этой страны? Или мне вообще надоело?

Ответы [ 3 ]

2 голосов
/ 15 июля 2010

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

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

1 голос
/ 15 июля 2010

Nevermind .. снова ответил на мой собственный вопрос при ответе на spinon ... не так уж сложно добавить очередь "ожидания":

    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');
0 голосов
/ 15 июля 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...