0

I got this

for(m in _data.data)
    {
        var _person= new Person(_data.data[m].Properties); //return a person object
        $('ul.v_list').append("<li>"+_person.person_name+'</li>').css("cursor", "pointer");

        $('ul.v_list').find('li:last').bind('click', function(){onPersonChanged(_person)});
    }

And this another function

 function onPersonChanged(person){
        alert("You have clicked " + person.person_name);
   };

Everytime is passing the last object created in the Person Object to the onPersonChanged function so it alerts the last name in the list if I click in the first li or another li element nested in the ul. eg.:

<ul class='v_list'>
     <li>James</li>
     <li>Paul</li>
     <li>Bonnie</l>
</ul>

When I do a click in Paul I expect an alert showing "You have clicked Paul" instead I always get the last one li in the list: "You have clicked Bonnie". How can I get the correct alert for the selected li?

1
  • i think hes having a closure problem.... Commented Feb 13, 2012 at 3:43

2 Answers 2

1

Your onPersonChanged function is being called after the loop has been executed therefore only the last _person in the loop will be passed through. Look up "closures" in javascript.

To fix it you should do the following:

for(m in _data.data)
{
    var _person= new Person(_data.data[m].Properties);
    (function(p) { 
        $('ul.v_list').append("<li>"+p.person_name+'</li>').css("cursor", "pointer");

        $('ul.v_list').find('li:last').bind('click', function(){onPersonChanged(p)});

    })(_person);
}

this will evaluate the current value of _person as it is at that point in the loop as opposed to evaluating it after the loop has finished.

The (function(p) { ... })(_person); is an anonymous self-executing function. this creates a new sub-scope in your for loop which will preserve the value of _person correctly.

Sign up to request clarification or add additional context in comments.

Comments

1

You want to create a closure for the current value of _person. But you need a function that will be immediately evaluated for that.

Your function in the bind statement is only evaluated when the click event occurs.

@Darko Z's code is a good example of how to fix.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.