It looks like method "one" (or "bind" with last argument true) in kendo.Observable doesn't work as expected if you try to bind several events at the same time.
Short example is at:
http://jsfiddle.net/737D2/
Expected result is 4 alerts in following order:
- "b"
- "Before a"
- "a"
- "After a"
Actual result is:
- "b"
- "Before a"
- "b"
- "b"
- "After a"
Is this a real bug or is it intended behavior?
In the source code I'm looking at now (Kendo UI Web v2013.3.1119), the bug is at \src\js\kendo.core.js in lines 90-126 where the method "bind" of the class
"Observable" is defined. More specifically, most probably lines 113-119 have to be patched. The bug is related to "closures".
Relevant code is:
for (idx = 0, length = eventNames.length; idx < length; idx++) {
eventName = eventNames[idx];
handler = handlersIsFunction ? handlers : handlers[eventName];
if (handler) {
if (one) {
original = handler;
handler = function () {
that.unbind(eventName, handler);
original.apply(that, arguments);
};
}
if (one) {
handler = (function (original, localEventName) {
var newHandler = function () {
that.unbind(localEventName, newHandler);
original.apply(that, arguments);
};
return newHandler;
})(handler, eventName);
}
events = that._events[eventName] = that._events[eventName] || [];
events.push(handler);
}
}
I think proper fix should be something like this (I didn't test it):
if (one) {
handler = (function (original, localEventName) {
var newHandler = function () {
that.unbind(localEventName, newHandler);
original.apply(that, arguments);
};
return newHandler;
})(handler, eventName);
}
Note that in this case "original", "localEventName" and "newHandler" are captured from the local scope and thus will not be affected by further iteration through for cycle.
Short example is at:
http://jsfiddle.net/737D2/
Expected result is 4 alerts in following order:
- "b"
- "Before a"
- "a"
- "After a"
Actual result is:
- "b"
- "Before a"
- "b"
- "b"
- "After a"
Is this a real bug or is it intended behavior?
In the source code I'm looking at now (Kendo UI Web v2013.3.1119), the bug is at \src\js\kendo.core.js in lines 90-126 where the method "bind" of the class
"Observable" is defined. More specifically, most probably lines 113-119 have to be patched. The bug is related to "closures".
Relevant code is:
for (idx = 0, length = eventNames.length; idx < length; idx++) {
eventName = eventNames[idx];
handler = handlersIsFunction ? handlers : handlers[eventName];
if (handler) {
if (one) {
original = handler;
handler = function () {
that.unbind(eventName, handler);
original.apply(that, arguments);
};
}
if (one) {
handler = (function (original, localEventName) {
var newHandler = function () {
that.unbind(localEventName, newHandler);
original.apply(that, arguments);
};
return newHandler;
})(handler, eventName);
}
events = that._events[eventName] = that._events[eventName] || [];
events.push(handler);
}
}
I think proper fix should be something like this (I didn't test it):
if (one) {
handler = (function (original, localEventName) {
var newHandler = function () {
that.unbind(localEventName, newHandler);
original.apply(that, arguments);
};
return newHandler;
})(handler, eventName);
}
Note that in this case "original", "localEventName" and "newHandler" are captured from the local scope and thus will not be affected by further iteration through for cycle.