Используйте запрашиваемые данные JSON в функции - PullRequest
0 голосов
/ 14 мая 2010

У меня есть код, подобный этому:

$.ajax({
        success: function(data) {
            text = '';
            for (var i = 0; i< data.length; i++) {
                text = text + '<a href="#" id="Data_'+ i +'">' + data[i].Name + "</a><br />";
            }            
            $("#SomeId").html(text);

            for (var i = 0; i< data.length; i++) {
                $("#Data_"+i).click(function() {
                    alert(data[i]);
                    RunFunction(data[i]);
                    return false;
                });                
            }
        }
    });

Получает массив некоторых данных в формате json, затем перебирает этот массив, генерируя ссылку для каждой записи. Теперь я хочу добавить функцию для каждой ссылки, которая будет запускать функцию, которая что-то делает с этими данными. Проблема в том, что данные кажутся недоступными после вызова функции успеха ajax (хотя я думал, что они ведут себя как замыкания). Как лучше использовать запрошенные данные JSON позже? (Я думаю, что установка его в качестве глобальной переменной сделает эту работу, но я хочу этого избежать, в основном потому, что этот запрос ajax может вызываться несколько раз)

Спасибо.

Ответы [ 3 ]

1 голос
/ 14 мая 2010

Вы можете использовать .bind() напрямую и передавать данные:

for (var i = 0; i< data.length; i++) {
    $("#Data_"+i).bind('click', {data: data[i]}, function() {
         alert(event.data.data);
          RunFunction(event.data.data);
          return false;
    });                
 }

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

См. Также Закрытие JavaScript для чайников (без обид), пример 5.

1 голос
/ 14 мая 2010

Ваша проблема в том, что переменная i является общей для обратных вызовов.

Следовательно, все обратные вызовы выполняются для последнего элемента.

Самое простое решение - использовать $.each:

        $.each(data, function(i) {
            $("#Data_"+i).click(function() {
                alert(data[i]);
                RunFunction(data[i]);
                return false;
            });                
        });

Это вызовет отдельный вызов функции для каждой итерации, поэтому для каждой итерации будет отдельная переменная i (или, в данном случае, параметр).

0 голосов
/ 14 мая 2010

SLaks ответ хороший, но он не смог объяснить , почему это не сработало.

Проблема связана с областью видимости. Попробуйте это:

var logger = function(x){
  console.log(x);
};
for(var j = 0; j < 10; j++){
  window.setTimeout(function(){
    logger(j);
  }, 1000);
}

Эта милая маленькая функция выводит только ... 9s! Это связано с тем, что ссылка на j сохраняется в течение времени ожидания, поэтому к моменту времени ожидания j уже установлено в 9.

Сравните это с:

var logger = function(x){
  console.log(x);
};
for(var j = 0; j < 10; j++){
  // we're wrapping our call in an anonymous function
  // don't do this in production code...make the function external instead
  // so you don't create 10 functions
  (function(k){
    window.setTimeout(function(){
      logger(k);
    }, 1000);
  })(j);
}

Эта версия оборачивает внутренний вызов в анонимную функцию, которая принимает в качестве аргумента индекса. Поскольку область действия k теперь ограничена этой функцией, регистратор работает так, как вы ожидаете.

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