Итерация по массиву при выполнении запроса для каждой записи - PullRequest
4 голосов
/ 30 декабря 2008

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

var LOCATION = 'http://www.google.com/ig/api?weather=';

$( document ).ready( function() {
    for( var cityIdx = 0; cityIdx < cities.length; cityIdx++ ) {
        $.ajax({
            type: 'GET',
            url: LOCATION + cities[ cityIdx ],
            dataType: 'xml',
            success: function( xml ) {
                if( $( xml ).find( 'problem_cause' ) != 0 ) {
                    // Do what I want with the data returned
                    var weather = $( xml ).find( 'temp_c' ).attr( 'data' );
                }
            }
        });
    }
});

Проблема, с которой я сталкиваюсь, заключается в том, что в функции успеха я не могу получить доступ к названию города (через города [cityIdx]). Я вставил alert () в цикл for и функцию успеха, и кажется, что цикл выполняется towns.length раз, затем я получаю оповещения функции успеха. Моя цель - просто просмотреть каждый город, чтобы узнать погоду и показать его на своей странице вместе с названием соответствующего города.

Кроме того, что бы вы предложили мне сделать, чтобы отделить контент от презентации?

Спасибо. :)

Ответы [ 5 ]

5 голосов
/ 30 декабря 2008

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

$(document).ready(function() {
    for (var cityIdx = 0; cityIdx < cities.length; cityIdx++) {
        new function() {
            var currentCity = cities[cityIdx];
            $.ajax({
                type: 'GET',
                url: LOCATION + currentCity,
                dataType: 'xml',
                success: function(xml) {
                    alert(currentCity);
                    if ($(xml).find('problem_cause') != 0) {
                        // Do what I want with the data returned
                        var weather = $(xml).find('temp_c').attr('data');
                    }
                }
            });
        }(); // the "();" calls the function we just created inline
    }
});
5 голосов
/ 30 декабря 2008

Я подозреваю, что ваша проблема похожа на пример в http://ejohn.org/apps/learn/. Индексная переменная cityIdx обновляется в замыкании, которое вы создаете, когда обрабатывается цикл for, поэтому к моменту запуска вашей успешной функции cityIdx будет указать на последний элемент в массиве. Решение состоит в том, чтобы использовать оцененную анонимную функцию для создания независимого контекста, где значение индекса не обновляется.

//...
success: (function(cities, idx) {
    return function( xml ) {
      if( $( xml ).find( 'problem_cause' ) != 0 ) {
        // Do what I want with the data returned
        // use cities[idx]
        var weather = $( xml ).find( 'temp_c' ).attr( 'data' );
      }
    };
  })(cities, cityIdx)
//...
3 голосов
/ 30 декабря 2008

Почему бы не использовать jQuery для перебора вашего массива? Используйте каждую функцию jQuery:

    var LOCATION = 'http://www.google.com/ig/api?weather=';

$( document ).ready( function() {

    $.each(cities, function()  {
    //assign the current city name to a variable
        var city = this;
        $.ajax({
                type: 'GET',
                url: LOCATION + city,
                dataType: 'xml',
                success: function( xml ) {
                    if( $( xml ).find( 'problem_cause' ) != 0 ) {
                        alert(city);
                            // Do what I want with the data returned
                        var weather = $( xml ).find( 'temp_c' ).attr( 'data' ); 
                    }
                }
        });
    });
});

Предупреждение в функции успеха отображает правильный город.

1 голос
/ 30 декабря 2008

По разным причинам я бы попытался вытянуть функцию успеха в отдельно определенную функцию, а затем создать замыкание для нее в вызове ajax, включающем название города. Итак, сначала отдельный обработчик успеха:

function city_success(xml, name) {
  // your success handling code here
}

А затем измените привязку успеха в вызове ajax:

success: function (xml) { city_success(xml, cities[ cityIdx ]); },
1 голос
/ 30 декабря 2008

Самое простое, что ваш AJAX-запрос должен вернуть название города.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...