knockout.js changing the hasfocus value does not update binding value

我怕爱的太早我们不能终老 提交于 2019-12-24 03:22:56

问题


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?


回答1:


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 edit property, it updates the hasfocus binding to blur the field, and, because of the bug, updates the value binding too. Because bindings are run in the order listed, the value binding gets updated first, which overwrites the field with the value of title in the view model.

A simple change that fixes this is to re-order the bindings so that hasfocus will run first: http://jsfiddle.net/mbest/ksCSn/8/




回答2:


You should use Blur when pressing enter, I've adjusted your JS Fiddle

But m.b you should try to use another event to update value instead of pressing enter for changing value? For example afterkeydown: Js Fiddle

Also see KnockoutJS documentation




回答3:


ValueAccessor is a function that will evaluate either to a plain property or a ko.observable, depending on what you passed to the binding.

In your example you are passing the stopEdit function, hence:

valueAccessor().call(viewModel)

equals to

viewModel.stopEdit.call(viewModel)

Passing viewModel to the function will reset the scope from this to your viewModel. In your example this will efectively set the edit property of your viewModel to false, thus You could also write this as

viewModel.edit(false);

The issue here is you are mixing up events, see U10's answer for a better approach on tackling this issue.



来源:https://stackoverflow.com/questions/12384096/knockout-js-changing-the-hasfocus-value-does-not-update-binding-value

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!