Knockout $ root绑定不会立即更新UI元素

时间:2015-06-18 20:00:30

标签: jquery knockout.js

我想在页面上显示$root,以便知道对象中的内容。 在第一个添加事件之后,添加的项目将添加到对象,但UI不会反映更改。仅在第二个添加事件时,第一个项目显示在UI上,但第二个项目在第三个添加事件之前不会显示,等等。

jsfiddle

HTML

<input type='text' data-bind='value: selectedItem' />
<input type='button' data-bind='click: addItem' value='add' />
<pre>vm = <span data-bind="text: ko.toJSON($root, null, 4)"></span></pre>

JS

$(document).ready(function () {
    var BaseVM = function () {
        var that = {};
        return that;
    };
    var TestVM = function () {
        var that = BaseVM();
        that.relatedItems = ko.observableArray(['pork', 'ham']);
        that.selectedItem = ko.observable('');
        that.addItem = function () {
            if (that.relatedItems().indexOf(that.selectedItem()) >= 0) {
                alert('existed');
            } else {
                that.relatedItems().push(that.selectedItem());
            }
        };
        that.removeItem = function () {
            if (that.relatedItems().indexOf(that.selectedItem()) >= 0) {
                that.relatedItems().remove(that.selectedItem());
            }
        };
        return that;
    };
    var vm = TestVM();
    ko.applyBindings(vm);
});

1 个答案:

答案 0 :(得分:3)

您在底层JavaScript数组上调用.push(和.remove),因此Knockout看不到更改。只有当其他事情导致整个事情重新呈现时,它才会接受变化。

Knockout redefines the array functions on observableArrays,当你在这些对象上调用它们时,它都会更新底层数组并通知任何订阅者。而不是:

that.relatedItems().push(that.selectedItem());

你需要这个:

that.relatedItems.push(that.selectedItem());

这是改变:

$(document).ready(function () {
    var BaseVM = function () {
        var that = {};
        return that;
    };
    var TestVM = function () {
        var that = BaseVM();
        that.relatedItems = ko.observableArray(['pork', 'ham']);
        that.selectedItem = ko.observable('');
        that.addItem = function () {
            if (that.relatedItems().indexOf(that.selectedItem()) >= 0) {
                alert('existed');
            } else {
                that.relatedItems.push(that.selectedItem());
            }
        };
        that.removeItem = function () {
            if (that.relatedItems().indexOf(that.selectedItem()) >= 0) {
                that.relatedItems.remove(that.selectedItem());
            }
        };
        return that;
    };
    var vm = TestVM();
    ko.applyBindings(vm);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type='text' data-bind='value: selectedItem' />
<input type='button' data-bind='click: addItem' value='add' />
<pre>vm = <span data-bind="text: ko.toJSON($root, null, 4)"></span></pre>