I have http://jsfiddle.net/ksCSn/1/
HTML
<input type="text" data-bind="
value: title,
hasfocus: edit,
onEnter: stopEdit" />
<p data-bind="text: title"></p>
JS
ko.bindingHandlers.onEnter = {
init: function(element, valueAccessor, _, viewModel) {
ko.utils.registerEventHandler(element, 'keydown', function(evt) {
if (evt.keyCode === 13)
valueAccessor().call(viewModel);
});
}
}
function ViewModel() {
this.title = ko.observable("default value");
this.edit = ko.observable(false);
this.stopEdit = function() {
this.edit(false);
// If the edit update is in a timeout, then it works
// var edit = this.edit;
// setTimeout(function() { edit(false); }, 0);
};
}
ko.applyBindings(new ViewModel());
How come when the Enter key is pressed while editing in the input field, the value does not update?
And if I change the edit update so that it is queued up as a timeout, then it works. Why is that?
This is because of a “bug” in Knockout (see https://github.com/SteveSanderson/knockout/issues/321) that causes all bindings to update together. When you change your
editproperty, it updates thehasfocusbinding to blur the field, and, because of the bug, updates thevaluebinding too. Because bindings are run in the order listed, thevaluebinding gets updated first, which overwrites the field with the value oftitlein the view model.A simple change that fixes this is to re-order the bindings so that
hasfocuswill run first: http://jsfiddle.net/mbest/ksCSn/8/