PDA

View Full Version : Make handlers' function use the loop variable value instead of its ref



simreno
12 Jan 2012, 3:10 AM
I've got a newbie question I guess: In a loop 'for' my code adds newly created buttons to a panel. I use SenchaTouch2-PR3 and runs contents on Chrome and Safari.

I wan't each button's handler to use the value of the incremented loop 'for' index. In below example: to set which panel is to be activated/showed depending on the button pressed.
I just don't manage to do it, because it seems that once initialized, my handlers' function points to the variable and not its value. So I retrieve last value of the variable index (index=3) in the below example.

Sample code to illustrate my problem:


for (var index=0,max=3; index<max; index++) {
buttonPanel.add(
// Buttons to switch among Panel's cards
Ext.create('Ext.Button', {
text: 'Switch to Panel '+index,
cls: 'abutton',
handler: function(container, event) {
Ext.global.console.log("[test] Switching to Panel #"+index);
switchingPanel.setActiveItem(index);
}
})
);
}

When running this sample code (the full test page is attached to this thread), and pressing any of the 3 created buttons, logs always display '[test] Switching to Panel #3'.
However, buttons' textual label is correct, i.e. displaying 'Switch to Panel [0; 1; 2]'.

I would like that each created button's handler sets the active item of 'switchingPanel' to 0, 1 or 2, and not 3, latest value of the variable index once the loop 'for' has finished its execution.

What am I missing here please?
I looked for a way to reach the variable 'index' value, but failed to.

Thank you for any help!

hendricd
12 Jan 2012, 5:18 AM
@simreno--

What you are struggling with is Javascript's variable scope. In your case, a function closure (handler) has been created that maintains a reference to the variable index, thus index will retain it's last value obtained by the for..loop

Better, would be to maintain the current value of index on the button config itself:



for (var index=0,max=3; index<max; index++) {
buttonPanel.add(
// Buttons to switch among Panel's cards
Ext.create('Ext.Button', {
text: 'Switch to Panel '+index,
cls: 'abutton',
cardIndex : index, //ByVal
handler: function(button, event) {
Ext.global.console.log("[test] Switching to Panel #"+index, button.cardIndex);
switchingPanel.setActiveItem(button.cardIndex);
}
})
);
}


Also a bit easier for the next guy to see what's going on.

simreno
12 Jan 2012, 5:25 AM
nice, thank you a lot for your help hendricd!
it's just working as expected now.
This tip will help me in many situations!
cheers