Why Do All Of The Keybindings In This Directive Get Overwritten By The Last One?
Solution 1:
You've fallen for a common trap: variables in JavaScript are always function scoped. When you do this:
for (var k in attribute) {
console.log('binding ' + k + ' as ' + attribute[k]);
Mousetrap.bind(k, function() { return attribute[k](scope, element); });
}
With that bind()
, you're creating four closures that all close over the variable k
—but they all close over the same variable. You don't get a new one for each run of the loop. The console.log
works perfectly because the value of k
is used immediately. The closure doesn't evaluate k
until it's actually run, and by then, its value has changed to whatever it was when the loop finished.
Depending on your target audience, the easiest way by far to fix this is to use let
instead of var
. let
does block scoping (which works about how you'd expect), but is a fairly recent invention, and I'm not sure how well it's supported.
Otherwise, to get a new scope, you need a new function:
for (var k in attribute) {
(function(k) {
console.log('binding ' + k + ' as ' + attribute[k]);
Mousetrap.bind(k, function() { return attribute[k](scope, element); });
})(k);
}
This passes the outer k
to the function's inner k
, which will be a different variable every time. You could also split this out into a little factory function, but for something this tiny, I wouldn't bother.
Post a Comment for "Why Do All Of The Keybindings In This Directive Get Overwritten By The Last One?"