【发布时间】:2014-05-01 12:51:49
【问题描述】:
虽然这可能看起来像许多关于敲除映射插件和部分视图模型更新的类似问题,但我在所有搜索中都没有看到我在这里遇到的问题。
我将在下面通过一个示例进行详细说明,但简而言之,这就是我想要做的。
首先我使用 KO Mapping 插件的 ko.mapping.fromJS 从 Javascript 对象创建视图模型。
现在我只想用从服务器接收到的数据更新视图模型的一部分。所以。
- 我使用
ko.mapping.toJS将 viewModel 转换为 JavaScript 对象 - 用服务器端的数据更新部分JS对象
- 使用更新的JS对象更新视图模型使用
ko.mapping.fromJS
问题
- 第一次通过映射从 JS 对象创建的 observables 的值即使在更新后也保持不变
- 如果服务器数据对象中存在新属性,它们会显示它们的值 在更新的视图模型中附带 - 但不会在后续更新中更新为新值。
这是一个简化的例子。
观点
<div>
<label data-bind="text: mainTitle"></label>
<div data-bind="with: layer0">
<label>Name - </label>
<label data-bind="text: name"></label>
<label>Type - </label>
<label data-bind="text: type"></label>
</div>
</div>
用于制作 ViewModel 的数据模型
var dataModel = {
mainTitle: "Main Title",
layer0:{
itemDetails:{
name:"item1name",
type:"type1"
},
otherDetails:{
prop1: "prop1Value",
prop2: "prop2Value"
}
}
这个JS对象dataModel通过
var viewModel = ko.mapping.fromJS(dataModel);
并通过 applyBindings 应用到上面的视图中,并按预期显示数据
现在我从服务器接收到这个 JS 对象
var newJSobjectFromServer = {
name: "item2Name",
description: "item2Description" // new property that was not on first model
type: "type2"
}
现在我做不到
viewModel.layer0.itemDetails(newJSobjectFromServer);
因为在由映射插件创建的viewModel 中,itemDetails 是属性而不是方法,只有 name 和 type 是方法
所以我先通过
从viewModel中提取一个JS对象var viewModelJS = ko.mapping.toJS(viewModel);
然后我用新的服务器数据更新viewModelJS 的一部分
viewModelJS.layer0.itemDetails = newJSobjectFromServer;
所以viewModelJS变成了
{
mainTitle: "Main Title",
layer0:{
itemDetails:{
name: "item2Name",
description: "item2Description" // new property
type: "type2"
},
otherDetails:{
prop1: "prop1Value",
prop2: "prop2Value"
}
}
}
然后我尝试通过
更新viewModelko.mapping.fromJS(viewModelJS , viewModel);
也试过了
ko.mapping.fromJS(viewModelJS , {}, viewModel);
但结果是
layer0.itemDetails.name() 仍然是 "item1" 和 layer0.itemDetails.type() 仍然是 "type1" 而新的 observable layer0.itemDetails.description() 存在并且具有值“item2Description”
现在如果我用另一个服务器返回的对象重复更新
{
name: "item3Name",
description: "item3Desctiption"
type: "type3"
}
这次viewModel 中的所有值都与上次相同
layer0.itemDetails.name() 仍然是 "item1" 和 layer0.itemDetails.type() 仍然是 "type1" 和
layer0.itemDetails.description() 仍然是 "item2Description",因此视图中没有任何变化。
处理对象的复杂性使我有必要使用映射插件,只是示例被简化,但确实完全描述了我面临的问题。我真的在找人来指导我如何在上述确切场景中使用来自服务器的数据更新 viewModel 的那一部分。如果解决了这个问题,我可以将它应用到我所面临的更复杂的现实世界场景中。提前致谢。
【问题讨论】:
标签: knockout.js knockout-mapping-plugin