2010-05-14 89 views
0

我有一个类似的代码:使用查询JSON数据在函数

$.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请求可能会被多次调用)

谢谢。

回答

1

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

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

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

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

这将使一个单独的函数调用对于每次迭代,所以会有对于每次迭代的单独i变量(或者,在此情况下,参数) 。

+0

这看起来不错,容易 – SztupY 2010-05-14 16:15:59

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

+0

没有冒犯。我确信,关闭不能如我所料,我只是不知道如何让他们工作。 – SztupY 2010-05-14 16:15:43

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