在函数中使用查询的json数据

时间:2010-05-14 14:42:16

标签: javascript jquery json closures visibility

我有类似的代码:

$.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 个答案:

答案 0 :(得分:1)

您的问题是回调共享i变量。

因此,所有回调都在最后一项上运行。

最简单的解决方案是使用$.each

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

这将为每次迭代进行单独的函数调用,因此每次迭代都会有一个单独的i变量(或者,在本例中为参数)。

答案 1 :(得分:1)

您可以直接使用.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 Closures for Dummies(无进攻),例5。

答案 2 :(得分:0)

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的范围现在仅限于该功能,因此记录器可以按预期工作。