Knockout绑定不会更新模型

时间:2016-03-07 15:45:21

标签: javascript mvvm knockout.js

我只是开始使用Knockout但我已经体验过在WPF中应用的MVVM。我遇到的问题是包装模型对象的我的Knockout视图模型不会更新该原始模型。这是一个小例子:

HTML

<select name="size" id="sel-size" data-bind="options: sizes, value: size"></select>

JS

// default settings
var settings = {
    size: 5
};

// settings view model
var settingsVM = function () {
    return {
        sizes: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        size: ko.observable(settings.size)
    }
}();

// subscribe to changes
settingsVM.size.subscribe(function() {
    alert("Model: " + settings.size + " / VM: " + settingsVM.size());
})

ko.applyBindings(settingsVM);

View in JSFiddle

更改下拉选项时,只会更新视图模型中的settingsVM.size(),但模型中的settings.size保持不变。

似乎用引用初始化observable并不会将该引用保留为属性访问器的支持字段。关于Knockout的MVVM方式我有什么遗漏?

3 个答案:

答案 0 :(得分:0)

当您更改select的值时,它实际上会覆盖您的size可观察内容。如果要设置后备字段类型排列,则必须使用具有读/写的计算observable。

此外,如果您确实要更新原始设置&#39;对象,你需要单独处理而不是settings.size属性。这样的东西将使原始模型与选择保持同步:

Double

JSFiddle

答案 1 :(得分:0)

Knockout的一个肮脏的小秘密就是它不是真正的MVVM。它没有与viewmodeling分开的数据建模结构,所以它只是VVM。在普通的应用程序设计中,数据模型位于服务器上,应用程序中的“模型”是一组简单的AJAX例程,用于将它们放入视图模型中。 Knockout并不关心AJAX,所以你如何处理你的应用程序部分取决于你(但通常很简单)。

在您的问题中,您希望模型自动更新以反映相应的viewmodel元素。那是多余的;你不清楚你需要一些单独的东西,只是从viewmode复制一个值。 viewmodel可以包含模型。但是如果你想要做更多的模型,那么你确实需要将模型元素一起收集在一个结构中,Will Jenkins建议使用subscribe是最简单的响应变化的方法在viewmodel中。

在下面的评论中,Will Jenkins将调出Knockout提供的实用程序函数,以便在JSON和observable之间进行转换。这些对于在模型和视图模型之间来回移动也很有帮助。

另请参阅:ko.mapping

答案 2 :(得分:0)

没有更新的原因是因为您的settings.size不是可观察的,并且您的代码未提供在html中使用settings.size作为选定的尺寸。

// default Model for settings
function settings(){
    this.size = ko.observable(5);
}

// settings view model
var settingsVM = function () {    
    return {
        sizes: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
        settings: new settings()
    }
}();

// subscribe to changes
settingsVM.settings.size.subscribe(function() {
    alert("model: " + settingsVM.settings.size());
})

ko.applyBindings(settingsVM);

请参阅更新的小提琴here