无法使用新数据对象更新Knockout UI

Cannot update Knockout UI with fresh data object

本文关键字:对象 更新 Knockout UI 数据 新数据      更新时间:2023-09-26

当我从服务器获取单个项目的新数据时,我当前在UI刷新方面遇到问题,该项目位于包装对象的observableArray中,该包装对象包含多个observables的对象。

考虑以下内容:

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...
} 

OK-问题是克隆最终会映射元数据,最终在尝试调用ko.mapping.fromJS时会导致递归。

解决方案是使用ko.mapping.toJS而不是ko.toJS创建克隆,这样您就可以获得一个干净的克隆(无需映射元数据)。

这是一个更新的小提琴:http://jsfiddle.net/rniemeyer/tDDBp/

我今天也偶然发现了一些我想分享的东西:

如果使用进行克隆

var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone));

然后,克隆将被剥夺任何计算的可观察性。它们将作为函数的最后一个值存在,但不再作为计算的可观测值。

如果你的物品是一个复杂的模型,有计算的可观察性,你想保留在你的克隆上,你可以做以下事情:

var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone), null, new itemModel());

其中itemModel是包含计算的可观察性的项目的复杂模型。