从对象无法更新视图模型

时间:2010-12-20 19:35:14

标签: knockout.js

我希望能够观察视图模型中的对象。我有一个简单的例子,没有按预期工作,有人能看到问题吗?

使用knockout 1.1.1,有2个输入:

<form data-bind="submit: save">
    <input type="text" data-bind="value: deckName" />
    <input type="text" data-bind="value: deck().Name" />
    <button type="submit">Go</button>
</form>

页面加载时,输入会获得默认值,但提交表单viewModel.deck().Name时不会更新,viewModel.deckName是。

<script type="text/javascript">
    var initialData = {"Name":"test"};

    var viewModel = {
        deck: ko.observable(initialData),
        deckName: initialData.Name,
        save: function() {
            ko.utils.postJson(location.href, { deck: this.deck, deckName: this.deckName });
        }
    };
    ko.applyBindings(viewModel);
</script>

在表单POST上,无论输入是什么,deck仍然会发送“test”,而deckName将是相应的输入值。

我真正想要的是能够观察对象viewModel.deck然后将其属性绑定到输入,但属性不会更新。

1 个答案:

答案 0 :(得分:7)

您提供的内容存在一些问题。

  1. 您只为第二个输入设置了一次值设置器,因为deck().Namestatic value(而不是ko.observableko.observableArray)。 (为了证明这在viewModel.deck({"Name":"updated test"});
  2. 之后将ko.applyBindings(viewModel);添加到脚本的末尾
  3. deckName是单向绑定 - 它是在初始applyBindings期间编写的,而viewModel将由用户或脚本对<input>所做的更改进行更新。但是,如果您对viewModel进行编程更改,则您的输入字段将不会更新以匹配。你想看看Knockout.js'value binding documentation的最后一部分。
  4. 略有改进的版本:

    <form data-bind="submit: save">
        <input type="text" data-bind="value: deckName" />
        <input type="text" data-bind="value: deck().Name" />
        <button type="submit">Go</button>
    </form>
    <script type="text/javascript">
        var initialData = {"Name":"test"};
    
        var viewModel = {
            deck: ko.observable(initialData),
            // Set up a two way binding
            deckName: ko.observable(initialData.Name),
            // Set up a one time value setter
            save: function() {
                ko.utils.postJson(location.href, ko.toJSON(this));
                // When we save the model we post *it* back, rather than
                // serializing it by hand.
            }
        };
        ko.applyBindings(viewModel);
        viewModel.deck({"Name":"updated test"});
    </script>
    

    使用fromJS的替代版本:

    <form data-bind="submit: save">
        <input type="text" data-bind="value: Name" />
        <button type="submit">Go</button>
    </form>
    <script type="text/javascript">
        var initialData = {"Name":"test"};
    
        var viewModel = ko.mapping.fromJS(initialData);
        viewModel.save = function() {
            ko.utils.postJson(location.href, ko.toJSON(this));
            // When we save the model we post *it* back, rather than
            // serializing it by hand.
        }
        ko.applyBindings(viewModel);
    </script>
    

    您需要查看Knockout的fromJSONfromJS个功能(在mapping plugin中实现)。