我有类似的代码:
$.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请求可能被多次调用)
感谢。
答案 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的范围现在仅限于该功能,因此记录器可以按预期工作。