JQuery вложенных вызовов Ajax не работает - PullRequest
0 голосов
/ 20 апреля 2011

Я пытаюсь делать вложенные вызовы 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 Ответ

1 голос
/ 20 апреля 2011

Вы понимаете, что ваши $.ajax вызовы асинхронны, верно? Это each:

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

Добавит <h4>, запустит асинхронный вызов $.ajax, а затем повторите для следующей записи в companies. Для вызовов AJAX почти наверняка потребуется больше времени, чем для $.each, поэтому он выдаст название компании <h4> s, а затем вызовы AJAX завершатся и добавят <p> s. Нет никакой гарантии, что <p> будут даже добавлены в правильном порядке.

Если вам нужно, чтобы все происходило в определенном порядке, вам придется добавить async: false к вашим $.ajax вызовам.

ОБНОВЛЕНИЕ : Мне нужно немного больше места, чем в комментарии. Нет, это не моя последняя теорема.

Вы можете вставить <h4> во внутренний обработчик успеха, но это все равно оставит вас открытым для проблем с упорядочением (т. Е. Второй вызов AJAX может завершиться до первого). Я думаю, что проще всего было бы добавить оболочку <div> s с атрибутами ID вокруг элементов <h4> и <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_hack и outer для нужного контекста и, таким образом, избежать обычных проблем с закрытием.

...