2011-10-03 127 views
2

我对JavaScript比较陌生,虽然我知道是什么导致了这个错误,但我不确定如何重构这个工作。在jQuery“ajax”中关闭工作方法

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事件的一些元素,其数据属性依赖于一些variableQueryValue改变每次迭代。由于绑定函数处理程序的关闭,在ajax请求中,它将绑定一个事件处理程序,该处理程序为每次迭代使用相同的variableQueryValue值。

我该如何重构这个,以便将更新的variableQueryValue考虑在内?

感谢您的帮助!

回答

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值。


还有其他解决方案来保留处理程序中使用的持久值的问题,但这可解决特定的关闭问题。根据实际情况,这可能是也可能不是你想要做的。

+0

感谢您的回答。感谢所有回答的人。我会看看,看看哪一个最适合我的情况:) – PolandSpring

+0

这些答案中的很多答案都是一样的(或者几乎相同的东西),只是语法不同而已。因此,如何编写代码实际上是个人偏好。 –

0

你可以使用.live()来达到这个目的吗?

的API说:

说明:将一个处理该事件对于当前选择现在和将来匹配这,所有的元素。

这个我认为可以解决这个事实,即在您添加事件的时候您的选择器不存在或者我误解了?

1

基本上,没有理由将其绑定到每个链接上。选择组并将事件处理程序绑定到组。

通过在for循环中调用.data(),将所需的任何值添加到addLink。然后在click事件处理程序中检索值。

0

你可以用每个回调创建封闭:

addLink.bind((function(variableQueryValue) { 
    return function() { 

     // variableQueryValue can be used here 
     $.ajax... 
    }; 
}(variableQueryValue))); 

这样一来,你会立即运行回调返回一个新的功能至极有一个局部变量保存的,所以它不能从改变外。

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); 
}