Данные HTML из нескольких запросов ajax в массив javascript

Я пытаюсь предварительно загрузить некоторый html-контент, используя AJAX и jQuery. Функция обратного вызова AJAX добавляет данные в ассоциативный массив. Я в порядке, если я делаю каждый запрос по отдельности:

var contentArray = new Object();

var urlA = "includes/contentA.php";
var urlB = "includes/contentB.php";
var urlC = "includes/contentC.php";

$.get(urlA, function(htmlA) {
    contentArray["A"] = htmlA;
});
$.get(urlB, function(htmlB) {
    contentArray["B"] = htmlB;
});
$.get(urlC, function(htmlC) {
    contentArray["C"] = htmlC;
});

Поскольку у меня, вероятно, будет несколько из них (более трех), я попытался сделать цикл for:

var contentArray = new Object();
var pages = new Object();

pages["A"] = "includes/contentA.php";
pages["B"] = "includes/contentB.php";
pages["C"] = "includes/contentC.php";

for (var key in pages) {
    var URL = pages[key];
    $.get(URL, function(html) {
        contentArray[key] = html;
    });
}

Однако это не работает. contentArray имеет только одно свойство, содержащее данные HTML, а не три. Я знаком с jQuery, особенно с AJAX, поэтому приветствуются как объяснения, так и решения (аналогичный или другой метод с одинаковым результатом).

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

Спасибо.


person Sam    schedule 03.09.2011    source источник


Ответы (1)


Функция обратного вызова для запроса AJAX не запускается до тех пор, пока запрос не вернется. В вашем случае каждая функция обратного вызова будет использовать key, поскольку она существует в текущем контексте, и, поскольку в ее локальной области нет переменной key, она будет использовать ближайшую, которую она может найти, key в вашем цикле for.

Проблема заключается в том, что к моменту возврата запросов AJAX цикл for уже полностью повторен, а key равен последнему ключу в массиве. Таким образом, каждая из функций обратного вызова будет получать одно и то же key, перезаписывая предыдущее значение в вашем contentArray.

Если вы используете jQuery 1.5.1 или выше, быстрое и грязное решение (которое не требует изменения текущей структуры ваших файлов PHP) может состоять в том, чтобы попробовать следующее:

for (var key in pages) {
  var URL = pages[key];

  $.ajax({
    url: URL,
    xhrFields: {
      'customData': key
    },
    success: function(html, statusText, jqXHR) {
      contentArray[jqXHR.customData] = html;
    }
  });
}

Я не проверял это, но, согласно странице документации, это должно работать. Все, что вы делаете, это используете объект запроса, созданный jQuery, для передачи вашей переменной функции обратного вызова.

надеюсь, это поможет

person Clive    schedule 04.09.2011
comment
Это работает, и спасибо! Я подумал, что это может быть проблема с областью действия, поэтому определил функцию для выполнения запроса ajax и добавления данных в contentArray. Это сработало, но я все еще не был уверен, что происходит. Теперь я знаю. Еще раз спасибо. - person Sam; 04.09.2011