2

我有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());

为什么在输入字段中编辑时按下 Enter 键,值不更新?

如果我更改编辑更新,使其作为超时排队,那么它就可以工作。这是为什么?

4

3 回答 3

8

这是因为 Knockout 中的一个“错误”(请参阅​​ https://github.com/SteveSanderson/knockout/issues/321)导致所有绑定一起更新。当您更改edit属性时,它会更新hasfocus绑定以模糊该字段,并且由于该错误,它value也会更新绑定。因为绑定是按列出的顺序运行的,所以绑定首先更新,这会用视图模型中value的值覆盖字段。title

解决此问题的一个简单更改是重新排序绑定,以便hasfocus首先运行:http: //jsfiddle.net/mbest/ksCSn/8/

于 2012-09-12T20:29:13.133 回答
0

ValueAccessor 是一个函数,它将评估为普通属性或 ko.observable,具体取决于您传递给绑定的内容。

在您的示例中,您正在传递 stopEdit 函数,因此:

valueAccessor().call(viewModel)

等于

viewModel.stopEdit.call(viewModel)

将 viewModel 传递给函数会将范围从 this 重置为您的 viewModel。在您的示例中,这将有效地将您的 viewModel 的编辑属性设置为 false,因此您也可以将其写为

viewModel.edit(false);

这里的问题是您正在混淆事件,请参阅 U10 的答案以获得解决此问题的更好方法。

于 2012-09-12T08:46:08.783 回答
0

按回车时你应该使用模糊,我已经调整了你的 JS Fiddle

但是 mb 您应该尝试使用另一个事件来更新值而不是按 enter 来更改值?例如afterkeydownJs Fiddle

另请参阅KnockoutJS 文档

于 2012-09-12T09:05:23.633 回答