2013-12-08 4 views
2

У меня есть набор вложенных вызовов Ajax, которые извлекают различные данные с сервера и изменяют группу элементов страницы на основе структуры таких данных, возможно, выполняя больше вызовов и меняется даже больше элементов, все для того, чтобы генерировать новое представление для пользователя:Набор очередей запросов AJAX и выполнение данных ответа в одном

$.ajax(
    //... 
    function() { 
     if(x) { 
      $('#element').html('...'); 
     } else { 
       $.ajax(// more similar changes, more ajax) 
     } 
    } 
) 

в настоящее время, приведенный выше код вызывает элементы должны быть повторно нарисованные последовательно. Тем не менее, я хотел бы, чтобы вся перерисовка произошла сразу - по крайней мере, с точки зрения пользователей, так что пользователь не испытывает ничего, кроме плавного перехода к новому представлению, не видя отдельных визуализаций.

Как я мог достичь этого?

+1

Я удалил теги [jQuery Animate] и [jQuery Отложенные] из вашего вопроса, поскольку я думаю, что они неактуальны. Кроме того, заголовок становится более читаемым и доступным для поиска. – TheCarver

ответ

2

ЕСЛИ НЕ ЗАВИСИМОСТИ ОТ КОНКРЕТНЫХ ОТВЕТОВ ОТ КАЖДОГО ЗАПРОС

JQuery имеет функцию .when() и .done(), что в вашем случае, будет выполнять все запросы AJAX первыми, и, когда все запросы будут завершены, вы можете сделать что-то со всеми данными ответа за один раз, поэтому пользователь не видит ступенчатого преобразования, поскольку различные запросы AJAX завершаются на разных этапах.

$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){ 
    // the code here will be executed when all four AJAX requests complete 
    // a1, a2, a3 and a4 contain lists of 3 items; the response text [0], 
    // the status [1], and an jqXHR object [2] for each of the listed AJAX calls 
    $('#element1').html(a1[0]); 
    $('#element2').html(a2[0]); 
    $('#element3').html(a3[0]); 
    $('#element4').html(a4[0]); 
}); 

function ajax1() { 
    return $.ajax({ 
     url: "someUrl.php", 
     dataType: "html", 
     data: myData, 
     ... 
    }); 
} 

function ajax2() {} // same as above 
function ajax3() {} // same as above 
function ajax4() {} // same as above 

Для получения дополнительной информации об использовании .when(), и чтобы узнать, как обрабатывать ошибки AJAX вызовов, проверьте jQuery documentation.

ЕСЛИ ВЫ ЗАВИСИМОСТИ ОТ КОНКРЕТНЫХ ОТВЕТОВ КАЖДОГО ЗАКАЗА

Вы можете хранить каждый ответ и идентификатор элемента в массив и работать с ними на одном дыхания позже, когда все вызовы AJAX являются полными. Нечто подобное могло бы помочь (с использованием кода из приведенных выше):

var myAjaxResponses = []; 
$.ajax(
    //... 
    function() { 
     if(x) { 
      myAjaxResponses.push({ 
       'elementID': "element1", 
       'responseData': x, 
      }); 
     } else { 
      $.ajax(
       function() { 
        if (x) { 
         myAjaxResponses.push({ 
          'elementID': "element2", 
          'responseData': x, 
         }); 
        } 
       } 
      ) 
     } 
    } 
) 

// loop through myAjaxResponses 
// adding the response data to each respective element 
function processResponses() { // called when last AJAX request finishes 
    $.each(myAjaxResponses, function (index, value) { 
     $('#'+value.elementID).html(value.responseData); 
    }); 
} 

Вот JSFIDDLE, чтобы показать идею массива работать.

+0

Я действительно зависим от них, к сожалению, они называются вложенными и генерируются в зависимости от результата каждого тэка на сервере. Таким образом, я не могу узнать, сколько или сколько вызовов Ajax будет вызываться в целом, когда я вызываю верхнюю часть цепочки, поэтому мне нужен способ собрать их все до того, как я сделаю рендеринг. – csvan

+0

@chrsva; О, хорошо, неважно.Я оставлю этот ответ здесь, поскольку это может помочь другим. Еще одно предложение; вы можете хранить каждый ответ в массиве '{elementID, responseData}', и когда все вызовы AJAX завершены '$ (document) .ajaxStop (executeMyResponses()) 'цикл через массив, добавляющий каждый ответный сигнал соответствующим элементам. – TheCarver

+0

Спасибо, я проверю! – csvan

0

Chrsva, можно предусмотреть три варианта:

  1. аккумулировать фрагментарные данные на сторону клиента и действовать на него, когда он будет завершен.
  2. Составьте весь набор данных на стороне сервера, доставьте его одним ударом, затем действуйте на нем.
  3. По мере поступления, действуйте по частям, обновляя клоны соответствующих фрагментов DOM, затем переставляя DOM DOM, когда все данные были доставлены.

Какой вариант вы выберете, отчасти зависит от того, что вы уже написали. Из того, что вы говорите в вопросе, наиболее привлекательным вариантом является уступка №3.

Ваша самая большая проблема может быть определена, когда сбор данных завершен.

+0

Не могли бы вы использовать '.ajaxStop (function() {})', чтобы определить, когда все вызовы AJAX завершены, а затем банковское переключение DOM? – TheCarver

+0

Мне никогда не приходилось использовать '.ajaxStop()', и было бы интересно, что в этом случае он может срабатывать преждевременно, но стоит попробовать. –

Смежные вопросы