2012-04-27 110 views
1

我有一个ajax请求,它返回我JSON数据(对象数组)。 迭代这个数组我生成一个链接列表。我想设置一个onClick事件并从ajax响应调用一个带params的函数。JavaScript:如何在动态生成的jQuery .click()函数中发送函数参数?

这听起来可能不太清楚,所以这里有一个例子:

function test(param1) { 
    // ... 
} 

$.ajax({ 
    url: 'getSomeData.php', 
    type: 'post', 
    data: data, 
    success: function(result){ 
     var result = JSON.parse(result); 
     $div = $('<div />'); 

     for (i in result.someObject) { 
      $div.append('<a href="#" id="linkID' + i + '">ajax link ' + i + '</a>'); 
      $('#linkID' + i).click(function(){ 
       test(result.someObject[i]); // <--- My question is here 
       return false; 
      }); 
     } 
     $(document.body).append($div); 
    } 
}); 

在我的功能test我总是得到迭代数组的最后一个对象。我有一些想法为什么发生这种情况,但我不知道如何解决它。

+0

@Anonymoose真实的,但无关描述的错误。如果宣布它将会失败。 – Alnitak 2012-04-27 10:23:20

回答

4

这是一个与范围的问题我的,如果你使用闭包来限制它的范围,像下面的点击事件处理程序,它应该没问题。

(function(i) { 
    $('#linkID' + i).click(function(){ 
    test(result.someObject[i]); // <--- My question is here 
    return false; 
    }); 
})(i); 

这可以保证我处于创建处理程序时的值,而不是它的最后一个值。

+0

这是正确的:'(function(i,j){/ * ... * /}(i,j);'如果我想限制多个变量的范围吗?我实际上不明白最后一部分'})(i);'它做了什么? – SaltLake 2012-04-27 10:48:24

+1

@SaltLake是的,这是多个参数的正确语法。最后一部分只是使用提供的参数立即调用该函数。使用'eventData'方法添加多个参数也很简单 - 只需将它们添加到地图即可。 – Alnitak 2012-04-27 11:20:52

0

可以通过使用jQuery.proxy()

简单实例传递一个上下文(以及因此变量):

MyObject = function() { 
    this.element = $('#element'); 
    this.some_var = 'It works!'; 

    this.element.click($.proxy(this.handleClick, this)); 
}; 

MyObject.prototype.handleClick = function() { 
    console.log(this.some_var); 
}; 

var m = new MyObject(); 

从jQuery文档示例:

<script> 
var me = { 
    type: "zombie", 
    test: function(event) { 
    // Without proxy, `this` would refer to the event target 
    // use event.target to reference that element. 
    var element = event.target; 
    $(element).css("background-color", "red"); 

    // With proxy, `this` refers to the me object encapsulating 
    // this function. 
    $("#log").append("Hello " + this.type + "<br>"); 
    $("#test").unbind("click", this.test); 
    } 
}; 

var you = { 
    type: "person", 
    test: function(event) { 
    $("#log").append(this.type + " "); 
    } 
}; 

// execute you.test() in the context of the `you` object 
// no matter where it is called 
// i.e. the `this` keyword will refer to `you` 
var youClick = $.proxy(you.test, you); 


// attach click handlers to #test 
$("#test") 
    // this === "zombie"; handler unbound after first click 
    .click($.proxy(me.test, me)) 
    // this === "person" 
    .click(youClick) 
    // this === "zombie" 
    .click($.proxy(you.test, me)) 
    // this === "<button> element" 
    .click(you.test); 
</script> 
2

你的问题是范围的一个 - 你的变量i没有被绑定在范围内,所以在事件处理程序被调用时它总是有最后一个赋值。

最简单的方法来解决这个(当您使用jQuery)是使用eventData参数.click()

('#linkID' + i).click({ param1: result.someObject[i] }, test); 

,然后更改test读取事件数据:

function test(ev) { 
    var param1 = ev.data.param1; 
    // ... 
} 

jQuery将绑定任何提供的eventData并自动将其添加到传递给事件处理程序的事件对象。

这样可避免必须创建任何附加闭包来修复提供的参数的范围。

见题为“通过事件数据”一节在http://api.jquery.com/bind/