Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot update Knockout UI with fresh data object

I'm currently having problems having the UI refresh when I'm getting new data from the server for a single item which is in an observableArray of wrapper objects which holds an object of several observables.

Consider the following:

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

Can someone explain why passing in the ItemWrapper into vm.selected isn't updating the UI whereas in (2) it works. I don't want to have to set-up each property like in (2) for every property.

ItemWrapper looks like so:

function PoolWrapper(pool) {
    this.Name = ko.observable(pool.Name);

    // more properties...
} 
like image 437
jaffa Avatar asked Feb 10 '12 10:02

jaffa


1 Answers

OK- the issue is that your clones end up with mapping meta-data on them and eventually this causes recursion when trying calling ko.mapping.fromJS.

The solution is to create your clones using ko.mapping.toJS instead of ko.toJS, so that you get a clean clone (without mapping meta-data).

Here is an updated fiddle: http://jsfiddle.net/rniemeyer/tDDBp/

like image 140
RP Niemeyer Avatar answered Nov 04 '22 21:11

RP Niemeyer