【问题标题】:jQuery nested Ajax calls not workingjQuery 嵌套的 Ajax 调用不起作用
【发布时间】:2011-08-09 17:20:24
【问题描述】:

我正在尝试进行嵌套的 ajax 调用,但迭代不起作用:假设我有 2 家公司,公司编号 1 有 2 个联系人,公司编号 2 有 3 个联系人。我不知道为什么,但下面给出的代码显示了两个公司名称,后跟五个联系人姓名:它不是嵌套的....

    <script type="text/javascript">
    $(function () {
        $('#searchbutton').bind('click', function (event) {
            $("#result > h4, #result > p").remove();
            $("<p>Loading...</p>").appendTo($("#result"));
            $.ajax({
                type: "GET",
                dataType: "jsonp",
                cache: true,
                url: "http://localhost/archilab/archilabdirectory.svc/",
                data: ("tag=" + $("#searchstring").val()),
                success: function (companies) {
                    $("#result > p").remove();
                    $.each(companies, function () {
                        var outer = this;
                        $("<h4>", { text: outer.Name + " (" + outer.Perimeter + ")" }).hide().appendTo($("#result")).show(4000, function () {
                            $.ajax({
                                type: "GET",
                                dataType: "jsonp",
                                cache: true,
                                url: "http://localhost/archilab/archilabdirectory.svc/" + outer.Name + "/contacts/",
                                success: function (contacts) {
                                    $(contacts).each(function () {
                                        $("<p>", { text: this.FirstName + " " + this.LastName }).hide().appendTo($("#result")).show();
                                    });
                                }
                            })
                        });
                    });
                }
            });
        })
    });
</script>

【问题讨论】:

  • 与其发出多个 ajax 调用,不如将姓名和联系人数据合并到一个 JSON 响应中,用于单个 ajax 请求?
  • 如果出于某种奇怪的原因需要两个,请写函数。始终编​​码 DRY(不要重复自己)。每当您可以将代码侧向一边看到山时,您就需要重构。

标签: jquery ajax nested jsonp each


【解决方案1】:

您确实意识到您的$.ajax 调用是异步的,对吗?这个each

$.each(companies, function () { /* ... */ });

将添加一个&lt;h4&gt;,启动一个异步$.ajax 调用,然后重复companies 中的下一个条目。 AJAX 调用几乎肯定比$.each 需要更长的时间才能完成,因此它会生成公司名称&lt;h4&gt;s,然后AJAX 调用将完成并添加&lt;p&gt;s。无法保证&lt;p&gt;s 甚至会以正确的顺序添加。

如果您需要按特定顺序发生事情,那么您将不得不将 async: false 添加到您的 $.ajax 调用中。

更新:我需要比评论提供更多的空间。不,这不是我的最后定理。

您可以将 &lt;h4&gt; 内容推送到内部成功处理程序中,但这仍然会让您面临排序问题(即第二个 AJAX 调用可能在第一个之前完成)。我认为最简单的做法是在&lt;h4&gt;&lt;p&gt; 元素周围添加带有ID 属性的包装器&lt;div&gt;s,这将为您提供.append 调用的简单目标;有点像这样:

$.each(companies, function() {
    var $wrapper_hack = $('<div/>');
    $('#result').append($wrapper_hack);
    add_content($wrapper_hack, outer);
});

// And elsewhere...
function add_content($wrapper_hack, outer) {
    $("<h4>", {
        text: outer.Name + " (" + outer.Perimeter + ")"
    }).hide().appendTo($wrapper_hack).show(4000, function () {
        $.ajax({
            /* ... */
            success: function(contacts) {
                /* Build your <p> and append it to $wrapper_hack */
            }
        });
    });
}

这个想法是将内容附加到右侧的&lt;h4&gt;,而不是附加到#result;然后,一切都会以正确的顺序出现,因为您在 HTML 元素嵌套中嵌入了正确的顺序。您需要将add_content 作为一个单独的函数来正确地将$wrapper_hackouter 本地化为所需的上下文,从而避免常见的关闭问题。

【讨论】:

  • 你说得对,我认为这实际上是发生的事情,但正如 jQuery API 所说,“跨域请求和数据类型:“jsonp”请求不支持同步操作”......那会是什么无需将所有公司和联系人召集在一起的最佳解决方案?
  • 效果很好,非常感谢!因为我的原型是 100% 面向客户端的,使用“原子”REST 调用来检索真正符合我需求的数据。再次感谢。
猜你喜欢
  • 2011-06-12
  • 1970-01-01
  • 1970-01-01
  • 2013-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-05
相关资源
最近更新 更多