javascript - Yeni veri nesnesi ile Knockout UI güncellenemiyor


Şu anda, birden fazla gözlemlenebilir içeren bir nesneyi tutan sarmalayıcı nesnelerden oluşan bir observableArray içindeki tek bir öğe için sunucudan yeni veri alırken kullanıcı arayüzünün yenilenmesiyle ilgili sorunlar yaşıyorum.

Şunları göz önünde bulundurun:

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

Birisi, ItemWrapper'ı vm.selected içine geçirmenin neden kullanıcı arayüzünü güncellemediğini açıklayabilir mi, oysa (2) numarada işe yarıyor. Her bir özelliği (2) numarada olduğu gibi ayarlamak zorunda kalmak istemiyorum.

ItemWrapper şu şekilde görünüyor:

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

    // more properties...
} 

Cevap #1

Tamam - sorun, kopyalarınızın üzerinde eşleme meta verilerinin olması ve bunun sonunda ko.mapping.fromJS çağırmaya çalışırken özyinelemeye neden olmasıdır.

Çözüm, temiz bir klon elde etmek (haritalama meta verisi olmadan) için ko.toJS yerine ko.mapping.toJS kullanarak klonlarınızı oluşturmaktır.

İşte güncellenmiş bir fiddle: http://jsfiddle.net/rniemeyer/tDDBp/

Cevap #2

Bugün aynı zamanda karşıma çıkan ve paylaşabileceğimi düşündüğüm bir şey:

Eğer şu şekilde klonlarsanız:

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

Sonra klon, herhangi bir hesaplanmış gözlemlenebilir öğeden arındırılacaktır. Bunlar işlevin son değeri olarak var olmaya devam edecek, ancak artık hesaplanmış bir gözlemlenebilir olarak işlev görmeyecektir.

Eğer öğeniz, klonunuzda tutmak istediğiniz hesaplanmış gözlemlenebilirlerle karmaşık bir modelse, aşağıdakileri yapabilirsiniz:

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

itemModel, hesaplanmış gözlemlenebilirlerinizi içeren öğeniz için karmaşık modelinizdir.