jQuery嵌套的Ajax调用不起作用

时间:2011-04-20 17:53:01

标签: jquery ajax nested jsonp each

我正在尝试进行嵌套的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>

1 个答案:

答案 0 :(得分:1)

您确实意识到您的$.ajax电话是异步的,对吧?这each

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

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

如果您需要按特定顺序执行某些操作,那么您必须在$.ajax来电中添加async: false

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

您可以将<h4>内容推送到内部成功处理程序中,但这仍然会让您对订购问题持开放态度(即第二次AJAX调用可能在第一次之前完成)。我认为最简单的方法是在<div><h4>元素周围添加包含ID属性的包装<p>,这样可以为.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 */
            }
        });
    });
}

我们的想法是将内容附加到右侧<h4>附加的内容而非附加到#result;然后,所有内容都将以正确的顺序显示,因为您已在HTML元素嵌套中嵌入了正确的顺序。您需要add_content作为单独的函数来正确地将$wrapper_hackouter本地化到所需的上下文,从而避免通常的闭包问题。