Reputation: 4374
I'm playing with mobile app creation with jQuery and an api I built using Slim.
My overall goal is to create a list of buttons that when clicked will call a function with the appropriate parameters.
I am successfully sending my request to slim, getting a list of users and storing the results in a global array of User objects.
Next I am iterating through the array appending html to the document to show the buttons. At the same time I am adding a click listener. The listener gets added, but not like I expect.
Users is an array of user objects with global scope. A user object can be boiled down to [{"name":"User's name"}].
Also relevant might be the fact that I'm doing this in a call back.
$.getJSON(url, function(data){
for(i=0;i<data.length;i++)
{
var u = new User();
u.name = data[i]['name'];
}
})
//The success handler DOES get called.
.success(function() {
for(var i=0; i<users.length; i++)
{
//this part works. users[i] is accessed as expected.
var html_string = '<li>'+users[i].name+'</li>';
$("#myUL").append(html_string);
$("#myUL li:last").click(function(){
//logs undefined
console.log(users[i].name);
//Handle the event
eventHandleFunction()
});
}
})
I'm well enough versed in programming in general to know that what I'm doing does not fall into best practices, but I am so illiterate in javascript that I don't know the right way to fix it. In addition to the howto answer I'd really appreciate anyone who took some time to point me to useful resources.
Update: After reading an answer about using delegate to assign handlers I have updated my code a bit. Now it looks like this. Note: I've only not updated the code above in order to get an answer to the 'why' part of the original question.
$("#myUL").delegate("li","click",function(){
//sets the attribute name of the global var user
user.name = $(this).text();
//lets see what user.name is now. Oh, look. It's what i expect
alert(user.name);
//do whatever else i want to do here.
});
//This json request is now (i believe) entirely unnecessary to answer the question.
$.getJSON(url, function(data){
for(i=0;i<data.length;i++)
{
var u = new User();
u.name = data[i]['name'];
}
})
//The success handler DOES get called.
.success(function() {
//No longer relevant
})
Upvotes: 0
Views: 284
Reputation: 318302
for(var i=0; i<users.length; i++) {
var numb = i,
html_string = '<li>'+users[numb].name+'</li>';
$("#myUL").append(html_string);
$("#myUL li:last").click(function(){
console.log(users[numb].name);
eventHandleFunction()
});
}
Upvotes: 0
Reputation: 31043
you can use delegate
$("#myUL").delegate("li:last","click",function(){
//event handler code here
});
this way you dont have to explicitly attach click event handler to every dynamically added li
in the DOM
if you are using jquery version 1.7+ then you can use .on
method like
$("#myUL").on("click","li:last",function(){
//event handler code here
});
the why part
the reason i see is the scope
for(var i=0; i<users.length; i++)
{
var html_string = '<li>'+users[i].name+'</li>';
$("#myUL").append(html_string);
$("#myUL li:last").click(function(){
//logs undefined BECAUSE i is undefined inside the click handler
console.log(users[i].name);
//Handle the event
eventHandleFunction()
});
}
Upvotes: 1