I'm working with JQuery and jsTree, and I've run into some confusion about how closures work.
I have an object that has a .jsTree member, and a .populateTree method. The method is called with an array of strings, with which it is supposed to create the nodes of the jsTree.
The jsTree builds a tree control, in which every node has an anchor "", which contains the text of the node. I want to make clicking on the text toggle the node open or closed, just like clicking on the +/- button in the tree. So I'm trying to add a click() function to do that, and I'm getting unexpected behavior.
So, here is the code:
populateTree: function populateTree(nodeNames)
{
if (!this.jsTree) // Note 1
return;
var me = this; // Note 2
for (var i = 0; i < nodeNames.length; i++)
{
var nodeName = nodeNames[i];
var node = this.jsTree.create_node(-1, "last", { state: 'open', data: nodeName }); //Note 3
this.jsTree.create_node(node, "last", { data: "child one" }); // Note 4
this.jsTree.create_node(node, "last", { data: "child two" });
this.jsTree.create_node(node, "last", { data: "child three" });
var anchor = node.find("a"); // Note 5
anchor.click(function() { me.jsTree.toggle_node(node); }); // Note 6
}
},
Note 1: This is a member function of a javascript object, so when it is called, "this" points to the object. The object contains a jsTree member variable, which should have already been initialized to contain a jsTree object, with no nodes.
Note 2: We are defining a "click" function at Note 6, and when that is called, "this" will not point to the object that contains the jsTree, so we save "this" in a variable called "me", which will be in scope when the "click" function executes, because creating the function created a closure, which included references to all variables that were in scope at the time the function was defined.
Note 3: For each element in the array, we create a top-level node (parent node is -1).
Note 4: For each top-level node we've created, we create three child nodes.
Note 5: Each node contains an anchor element (""), and it's this that we want to attach a "click" function to.
Note 6: Inside the "click" function, "me" should point to the object that contains the tree (see Note 2), and "node" should point to the node that we just created, in the current pass through the loop (see Note 3).
My problem? No matter which of the anchors I click on, it's always the last top-level node that opens and closes. It's like the closure for each of the "click" functions we've created has a closure that references only the last "node" variable. And that's not the way I thought closures worked.
Can someone help me understand where I went wrong in my understanding?
Thanks.