我对javascript相对较新,虽然我知道是什么导致了这个错误,但我不确定如何重构它以使其正常工作。
for ( ... ) {
var variableQueryValue = i
addLink.bind('click', function() {
$.ajax({
type: 'POST',
url: '/example',
data: 'queryvalue=' + variableQueryValue,
success: function(data) {
console.log('Got into success method!');
}
});
});
}
所以基本上我们将click事件绑定到某个元素,该元素的data属性依赖于一些每次迭代都会改变的variableQueryValue。由于绑定函数处理程序的关闭,在ajax请求中它将绑定一个事件处理程序,该处理程序为每次迭代使用相同的variableQueryValue值。
如何重构这一点,以便考虑更新的variableQueryValue?
感谢您的帮助!
答案 0 :(得分:4)
function create_handler( j ) {
return function( e ) {
$.ajax({
type: 'POST',
url: '/example',
data: 'queryvalue=' + j,
success: function(data) {
console.log('Got into success method!');
}
});
};
}
for ( ... ) {
addLink.bind('click', create_handler( i ) );
}
调用一个创建处理程序的函数,将i
传递给该函数。然后让该函数返回要分配给.bind('click',...
的处理程序。
这是因为当您调用函数时,您将创建一个新的变量环境。因此,当您将i
的值传递给函数,并在同一函数内创建处理程序时,您的处理程序现在引用传递到该特定变量环境的值。
处理程序将保留创建它的原始变量环境(即使您正在返回处理程序),因此它将始终引用正确的i
值。
对于保留处理程序中使用的持久值的问题,还有其他解决方案,但这解决了特定的闭包问题。根据实际情况,这可能是您想要做的,也可能不是。
答案 1 :(得分:1)
从根本上说,没有理由将它单独绑定到每个链接。选择组并将事件处理程序绑定到组。
通过调用for循环中的addLink
,为.data()
添加所需的任何值。然后在click事件处理程序中检索该值。
答案 2 :(得分:1)
在for循环的每次迭代期间,您需要使用值i
关闭变量。
for ( ... ) {
(function(variableQueryValue){
addLink.bind('click', function() {
$.ajax({
type: 'POST',
url: '/example',
data: 'queryvalue=' + variableQueryValue,
success: function(data) {
console.log('Got into success method!');
}
});
});
})(i);
}
答案 3 :(得分:0)
你可以为此目的使用.live()吗?
API说:
描述:为现在和未来与当前选择器匹配的所有元素附加事件的处理程序。
我认为这样可以满足您在添加活动时选择器不存在的事实......或者我是否误解了?
答案 4 :(得分:0)
您可以包装每个回调以创建闭包:
addLink.bind((function(variableQueryValue) {
return function() {
// variableQueryValue can be used here
$.ajax...
};
}(variableQueryValue)));
这样,您将立即运行回调函数,返回一个保存了局部变量的新函数,因此无法从外部更改。