Muhammad Usman
Muhammad Usman

Reputation: 10946

Jquery bind/live with dynamic values

I am binding a function to an html element.

there is some data in loop which is changing on each iteration

data = {
    networkId: networkId,
    network_avatar: network_avatar,
    network_user_name: network_user_name,
}

Here I am binding it:

$("#element"+i).bind(function(){ 
    change(data);
}

The function is:

function change(data){
    console.log(data);
}

There should be the different data in data variable on each iteration.

But the it always contains the content of last iteration.
Why jQuery changes the data that is already binded with change() function

Upvotes: 0

Views: 117

Answers (2)

Kevin Bowersox
Kevin Bowersox

Reputation: 94499

Try nesting the function within another function to create a closure. The trick with a closure is that you must have two nested functions, an inner function and an outer function. The inner function will possess a copy of the outer functions variables & parameters, in a sense inheriting its scope. In my example bindClick serves as the outer function, while the anonymous function within the call to $.click() serves as the inner function. This results in the anonymous inner function retaining the data object passed into the bindClick() method as a parameter. When we run this in a loop we essentially end up with 10 closures that remember the data object they were created with.

Live Example: http://jsfiddle.net/cDwEk/1/

function bindClick(data){
  $("#element" + data.myProp).click(function(){
         //anonymous function will remember state of outer functions variables.
         alert(data.myProp);     
    });    
}

//ForLoop
for(var i = 0; i < 10; i++){
    var data = {myProp:i};
    //Pass function to another function to create closure.
    bindClick(data);
}

Upvotes: 1

Vladislav Qulin
Vladislav Qulin

Reputation: 1942

First of all, don't use global variables named "data" or "window" or anything else like this. If the declaration of your variable data is somewhere in vision area use "var" bareword.

When the event handler is called, it calls the "change" function and sending the current value of data in it. What you need, is to declare own data for each handler. And you should use "var" for it. Like:

$("#element"+i).bind(function(){
   var currentDataValue = new CopyData(data);
   change(currentDataValue);
}

function CopyData(object) {
   var data = {};
   for (var val in object)
      data[val] = object[val];
   return data;
}

I guess it should help. But i'm not too sure.

Upvotes: 1

Related Questions