当我从服务器获取单个项目的新数据时,我正在遇到UI刷新问题,该项目位于包含多个可观察对象的包装对象的observableArray中。
请考虑以下事项:
var vm = {
....
localEdited: ko.mapping.fromJS(new ItemWrapper(defaultModelSerialised)),
selected: ko.observable(null),
editItem: function(data) {
// clone a temporary copy of data for the dialog when opening (*.localEdited on dialog)
var clonedData = ko.toJS(data);
ko.mapping.fromJS(clonedData, null, this.localEdited);
// selected should now point to the item in the obserable array which will be refreshed
this.selected(data);
// open dialog...
},
submitDialog: function(data) {
// submit data to server...
// (1) commit the data back to UI (new item is return in resp.entity from server)
vm.selected(new ItemWrapper(resp.entity));
// at this point the UI isn't showing the updated value
// (2) however if I do this it reflects the data change in the UI
this.selected().Name("changed"); // updates the UI.
}
有人可以解释为什么将ItemWrapper传入vm.selected不会更新UI,而在(2)中它可以工作。我不想为每个属性设置像(2)中的每个属性。
ItemWrapper看起来像这样:
function PoolWrapper(pool) {
this.Name = ko.observable(pool.Name);
// more properties...
}
答案 0 :(得分:6)
好的 - 问题是你的克隆最终会在它们上映射元数据,最终在尝试调用ko.mapping.fromJS
时会导致递归。
解决方案是使用ko.mapping.toJS
而不是ko.toJS
来创建克隆,以便获得干净的克隆(无需映射元数据)。
这是一个更新的小提琴:http://jsfiddle.net/rniemeyer/tDDBp/
答案 1 :(得分:0)
我今天偶然发现了一些我认为我会分享的内容:
如果使用以下方法克隆:
var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone));
然后克隆将删除任何计算的可观察量。它们将作为函数的最后一个值存在,但不再作为计算的可观察对象。
如果您的项目是具有计算可观察量的复杂模型,您希望保留在克隆上,则可以执行以下操作:
var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone), null, new itemModel());
其中itemModel是包含计算的observable的项目的复杂模型。