【问题标题】:How to avoid 3 ajax calls?如何避免 3 个 ajax 调用?
【发布时间】:2010-07-14 23:17:32
【问题描述】:

我写了一些代码,在你选择国家后过滤省/州选择字段:

    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 个 em 都访问服务器以获取省份列表,因为尚未返回任何 ajax 调用。

如果该国家/地区的 ajax 调用已经在进行中,是否有一种相对简单的方法告诉它“等待”?还是我应该打扰?

【问题讨论】:

    标签: jquery ajax synchronization


    【解决方案1】:

    我会说可能会在您的方法之外添加一个属性到缓存或其他一些对象,以指示当前是否正在加载缓存。在调用 ajax 方法之前将值设置为 true,然后在 ajax 调用的成功函数中将其设置为 false,一旦它完成。如果这是真的,那么你会跳过任何后续调用,直到该值为假。

    只有一种可能的解决方案。

    【讨论】:

    • 是的,真/假部分是简单的部分(确定数据是否已经被请求)......但是你如何插入延迟?我猜你添加了一个“waitingOn”队列......当ajax完成方法触发你遍历所有服务员......
    • 看来你已经明白了。很高兴我能帮忙,如果我愿意的话。好像是你自己想出来的。只需要一个小指针。
    【解决方案2】:

    没关系..在回复 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');
    

    【讨论】:

      【解决方案3】:

      我会说这取决于用例。用户是否总是必须通过这些元素?如果是这样,我可能倾向于在页面加载时抓取所有数据,甚至首先将数据与页面一起发送。

      还取决于您要处理的项目数量,也许自动完成会是更好的解决方案。

      真的需要更好的感觉让应用程序更强烈地建议

      【讨论】:

      • 好吧,我不想获取所有国家/地区的所有数据.. [可能] 很多数据... 它默认为加拿大,这是我们的目标受众.. . 如果他们从不切换国家/地区,那么其他国家/地区的数据从不需要加载。将对更大的列表使用相同的脚本(过滤数千个元素)。自动完成并不是很合适,因为结果列表仍然相对较小(少于 50 个选项)。
      • “通过”?他总是必须选择一个省/州,是的。 (除非默认值是偶然正确的)
      猜你喜欢
      • 1970-01-01
      • 2020-02-15
      • 1970-01-01
      • 2013-01-19
      • 1970-01-01
      • 2017-03-30
      • 2019-08-12
      • 1970-01-01
      • 2018-07-04
      相关资源
      最近更新 更多