PDA

View Full Version : Event handler within for-loop



ethanlam
5 May 2010, 7:29 PM
Hi all,

I'm creating a TreePanel which is built based on an array returned from Ajax call. The parent node is the text return from the array and each of them contains children which a listener is registered for an action.

Here is my code:


var nodeArray = []; //The tree structure used to refresh the TreePanel

// Prepare the config tree by looping the config items returned
for(var i = 0; i < this.data.length; i++){
var oneItem = this.data[i];
var configName = oneItem.text;

//Parent node - config Name
var node = {
text: configName, // displayed properly
leaf: false,
children: [],
}
var childNode = {
text: 'Contacts',
listeners: {'click': function() {
var context={_configName: configName }; // problem here!
MyClass.changePane(context);
}
},
id: 'Contacts_'+i,
leaf: true
}
node.children.push(childNode);

//Add the parent node to the nodeArray
nodeArray.push(node);
}
//return the tree structure here
return nodeArray;The problem is, whenever I click any children and the listener is triggered, the configName used is always the last item in the source 'data' array. I searched from other posts and seems it is because I'm attaching an anonymous method to the event, therefore a single copy is being overwritten until the last element in the source 'data' array.

I'm new to ExtJS and tried different ways by trial and error, still cannot find a correct way for this.

Any suggestion is appreciated!

evant
5 May 2010, 7:35 PM
Wrap it in a closure:



Ext.onReady(function(){
var p = new Ext.Panel({
renderTo: document.body,
width: 400,
height: 400
});

for(var i = 0; i < 10; ++i){
var c = p.add({
title: 'Panel' + i
});
(function(){
var j = i;
c.on('render', function(){
console.log(j);
});
})();
}
p.doLayout();
});

ethanlam
5 May 2010, 8:50 PM
Hi Evan,

Thanks for your prompt reply!

I'm not sure if I get this right, here is my updated code on creating the child node:


// Wrap in a closure
var childNode = new Ext.tree.TreeNode({
text: 'Contacts',
leaf: true
});

(function(){
var j = configAlias;
childNode.on('click', function(){
var loc_alias = configAlias
var context={_config_alias: loc_alias};
MyClass.changePane(context);
});
})();In FireBug, I can see the childNode is registered with the event (events->click->listeners->0->fn function()). However, when I click on the items, no action is triggered at all. And I don't see the lines inside the function is being visited adding breakpoints.

Any ideas? Thanks!

evant
5 May 2010, 8:53 PM
Something like that should work, but really you're doing it the hard way. First off, you can bind a click handler for the whole tree:



tree.on('click', function(node){
console.log(node);
});


Second, you can apply attributes to the node and read from them:



var n = new Ext.tree.TreeNode({
myProperty: 'foo'
});
console.log(n.attributes.myProperty);