Monday, 2 May 2016

How can you create a closure in a loop that which captures variables and takes parameters in Javascript?



I am trying to create a click event handler for a vis.js network like the one shown in this example:





network.on("click", function (params) {
params.event = "[original event]";
document.getElementById('eventSpan').innerHTML = '

Click event:

' + JSON.stringify(params, null, 4);
console.log('click event, getNodeAt returns: ' + this.getNodeAt(params.pointer.DOM));
});`



However I am trying to do so in a loop and would like to have the anonymous event handling function be able to use local variables in the loop (before they are changed in successive iterations).




For example:



for (data in data_list) {
var network = new vis.Network(data['container'], data['data'], data['options']);
network.on("click", function(params) {
console.log(data) // On event, data always equal to last element in data_list. I want it to save the data from the iteration this function was created in
console.log(params) // I also need to access 'params'
}
}



I understand that this should be done with a closure, however I could not find any examples of how to do this while also maintaining access to the 'params' passed in. How can I create a closure which can accept the 'params' argument but also save the state of 'data'?


Answer



I typically externalize the function, pass it the data I want to keep around and return a function that accepts the handlers parameters:



function getOnClickHandler(data) {
return function(params) {
console.log(data);
console.log(params);
}

}

for (data in data_list) {
var network = new vis.Network(data['container'], data['data'], data['options']);
network.on("click", getOnClickHandler(data));
}

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...