【问题标题】:Updating view model from object not working从对象更新视图模型不起作用
【发布时间】:2011-05-28 10:46:05
【问题描述】:

我希望能够观察视图模型内的对象。我有一个没有按预期工作的简单示例,任何人都可以看到问题吗?

使用淘汰赛 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 无论输入如何都将发送“测试”,而deckName 将是相应的输入值。

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

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    您提供的内容有几个问题。

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

    稍微改进的版本:

    <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 中实现)。

    【讨论】:

    • 关于deckName 单向绑定的要点。我想要的是一个带有“deck”作为可观察对象的视图模型,它来自 JSON,然后能够将其他属性添加到不来自 JSON 的视图模型中。
    • @yanta -- 在调用fromJSON 之后,您可以添加不是来自 JSON 对象的其他属性。该模型可以以编程方式构建;不必一口气将所有内容放在一起。
    • @Sean Vieira - 我将您的第二个示例复制到页面中,但 viewModel 未定义,名称未在输入中显示,并且表单未发布。有什么想法吗?
    • @yanta -- 你是否在页面上包含了 knockout.mapping 扩展? github.com/SteveSanderson/knockout.mapping
    • 啊,ko.fromJS 应该是 ko.mapping.fromJS :)
    猜你喜欢
    • 1970-01-01
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    • 1970-01-01
    • 2011-08-09
    相关资源
    最近更新 更多