javascript - Kan inte uppdatera Knockout UI med nytt dataobjekt
Jag har för närvarande problem med att få användargränssnittet att uppdateras när jag får ny data från servern för ett enskilt objekt som finns i ett observableArray av wrapper-objekt som innehåller ett objekt med flera observables.
Tänk på följande:
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.
}
Kan någon förklara varför det att passera in ItemWrapper i vm.selected inte uppdaterar användargränssnittet medan det fungerar i (2). Jag vill inte behöva ställa in varje egenskap som i (2) för varje egenskap.
ItemWrapper ser ut så här:
function PoolWrapper(pool) {
this.Name = ko.observable(pool.Name);
// more properties...
}
Svar #1
OK - problemet är att dina kloner hamnar med kartläggningsmetadata på sig och så småningom orsakar detta rekursion när man försöker anropa ko.mapping.fromJS.
Lösningen är att skapa dina kloner med ko.mapping.toJS istället för ko.toJS, så att du får en ren klon (utan kartläggningsmetadata).
Här är en uppdaterad fiddle: http://jsfiddle.net/rniemeyer/tDDBp/
Svar #2
Något jag också snubblade över idag som jag tänkte dela med mig av:
Om du klonar med:
var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone));
Då kommer klonen att berövas alla beräknade observabler. De kommer att finnas kvar som det sista värdet av funktionen, men fungerar inte längre som en beräknad observabel.
Om din artikel är en komplex modell med beräknade observerbara som du vill behålla på din klon kan du göra följande:
var clone = ko.mapping.fromJS(ko.mapping.toJS(itemToClone), null, new itemModel());
Där itemModel är din komplexa modell för din artikel som innehåller dina beräknade observabler.
