在JQuery“ajax”方法中解决闭包问题

时间:2011-10-03 19:07:45

标签: javascript jquery

我对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?

感谢您的帮助!

5 个答案:

答案 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)));

这样,您将立即运行回调函数,返回一个保存了局部变量的新函数,因此无法从外部更改。