Skip to content

Commit

Permalink
"event" binding now correctly handles registering multiple event hand…
Browse files Browse the repository at this point in the history
…lers at once
  • Loading branch information
SteveSanderson committed Feb 13, 2011
1 parent 812a6fa commit 4ba2eb1
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 55 deletions.
53 changes: 28 additions & 25 deletions build/output/knockout-latest.debug.js
Expand Up @@ -1101,32 +1101,35 @@ ko.utils.arrayForEach(eventHandlersWithShortcuts, function(eventName) {
ko.bindingHandlers['event'] = {
'init' : function (element, valueAccessor, allBindingsAccessor, viewModel) {
var eventsToHandle = valueAccessor() || {};
for(var eventName in eventsToHandle) {
if (typeof eventName == "string") {
ko.utils.registerEventHandler(element, eventName, function (event) {
var handlerReturnValue;
var handlerFunction = valueAccessor()[eventName];
var allBindings = allBindingsAccessor();

try {
handlerReturnValue = handlerFunction.apply(viewModel, arguments);
} finally {
if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true.
if (event.preventDefault)
event.preventDefault();
else
event.returnValue = false;
for(var eventNameOutsideClosure in eventsToHandle) {
(function() {
var eventName = eventNameOutsideClosure; // Separate variable to be captured by event handler closure
if (typeof eventName == "string") {
ko.utils.registerEventHandler(element, eventName, function (event) {
var handlerReturnValue;
var handlerFunction = valueAccessor()[eventName];
var allBindings = allBindingsAccessor();

try {
handlerReturnValue = handlerFunction.apply(viewModel, arguments);
} finally {
if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true.
if (event.preventDefault)
event.preventDefault();
else
event.returnValue = false;
}
}
}

var bubble = allBindings[eventName + 'Bubble'] !== false;
if (!bubble) {
event.cancelBubble = true;
if (event.stopPropagation)
event.stopPropagation();
}
});
}
var bubble = allBindings[eventName + 'Bubble'] !== false;
if (!bubble) {
event.cancelBubble = true;
if (event.stopPropagation)
event.stopPropagation();
}
});
}
})();
}
}
};
Expand Down
2 changes: 1 addition & 1 deletion build/output/knockout-latest.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions spec/defaultBindingsBehaviors.js
Expand Up @@ -430,11 +430,17 @@ describe('Binding: Event', {
before_each: prepareTestNode,

'Should invoke the supplied function when the event occurs, using model as \'this\' param': function () {
var model = { wasCalled: false, doCall: function () { this.wasCalled = true; } };
testNode.innerHTML = "<button data-bind='event:{someEvent:doCall}'>hey</button>";
var model = {
firstWasCalled: false, firstHandler: function () { this.firstWasCalled = true; },
secondWasCalled: false, secondHandler: function () { this.secondWasCalled = true; }
};
testNode.innerHTML = "<button data-bind='event:{firstEvent:firstHandler, secondEvent:secondHandler}'>hey</button>";
ko.applyBindings(model, testNode);
ko.utils.triggerEvent(testNode.childNodes[0], "someEvent");
value_of(model.wasCalled).should_be(true);
ko.utils.triggerEvent(testNode.childNodes[0], "firstEvent");
value_of(model.firstWasCalled).should_be(true);
value_of(model.secondWasCalled).should_be(false);
ko.utils.triggerEvent(testNode.childNodes[0], "secondEvent");
value_of(model.secondWasCalled).should_be(true);
},

'Should prevent default action': function () {
Expand Down
53 changes: 28 additions & 25 deletions src/binding/defaultBindings.js
Expand Up @@ -18,32 +18,35 @@ ko.utils.arrayForEach(eventHandlersWithShortcuts, function(eventName) {
ko.bindingHandlers['event'] = {
'init' : function (element, valueAccessor, allBindingsAccessor, viewModel) {
var eventsToHandle = valueAccessor() || {};
for(var eventName in eventsToHandle) {
if (typeof eventName == "string") {
ko.utils.registerEventHandler(element, eventName, function (event) {
var handlerReturnValue;
var handlerFunction = valueAccessor()[eventName];
var allBindings = allBindingsAccessor();

try {
handlerReturnValue = handlerFunction.apply(viewModel, arguments);
} finally {
if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true.
if (event.preventDefault)
event.preventDefault();
else
event.returnValue = false;
for(var eventNameOutsideClosure in eventsToHandle) {
(function() {
var eventName = eventNameOutsideClosure; // Separate variable to be captured by event handler closure
if (typeof eventName == "string") {
ko.utils.registerEventHandler(element, eventName, function (event) {
var handlerReturnValue;
var handlerFunction = valueAccessor()[eventName];
var allBindings = allBindingsAccessor();

try {
handlerReturnValue = handlerFunction.apply(viewModel, arguments);
} finally {
if (handlerReturnValue !== true) { // Normally we want to prevent default action. Developer can override this be explicitly returning true.
if (event.preventDefault)
event.preventDefault();
else
event.returnValue = false;
}
}
}

var bubble = allBindings[eventName + 'Bubble'] !== false;
if (!bubble) {
event.cancelBubble = true;
if (event.stopPropagation)
event.stopPropagation();
}
});
}
var bubble = allBindings[eventName + 'Bubble'] !== false;
if (!bubble) {
event.cancelBubble = true;
if (event.stopPropagation)
event.stopPropagation();
}
});
}
})();
}
}
};
Expand Down

0 comments on commit 4ba2eb1

Please sign in to comment.