我只是开始使用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);
更改下拉选项时,只会更新视图模型中的settingsVM.size()
,但模型中的settings.size
保持不变。
似乎用引用初始化observable
并不会将该引用保留为属性访问器的支持字段。关于Knockout的MVVM方式我有什么遗漏?
答案 0 :(得分:0)
当您更改select的值时,它实际上会覆盖您的size可观察内容。如果要设置后备字段类型排列,则必须使用具有读/写的计算observable。
此外,如果您确实要更新原始设置&#39;对象,你需要单独处理而不是settings.size属性。这样的东西将使原始模型与选择保持同步:
Double
答案 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