2012-02-10 13 views
6

Attualmente sto avendo problemi con l'aggiornamento dell'interfaccia utente quando ricevo nuovi dati dal server per un singolo oggetto che si trova in un array osservabile di oggetti wrapper che contiene un oggetto di più osservabili .Impossibile aggiornare l'interfaccia utente Knockout con l'oggetto dati nuovo

Si consideri il seguente:

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

qualcuno può spiegare perché passando l'ItemWrapper in vm.selected non aggiorna l'interfaccia utente, mentre in (2) funziona. Non voglio dover impostare ogni proprietà come in (2) per ogni proprietà.

ItemWrapper assomiglia così:

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

    // more properties... 
} 
+0

È possibile associare qualcosa a vm.selected in html? In caso contrario, perché ti aspetti che Koutout aggiorni l'interfaccia utente in questa riga vm.selected (new ItemWrapper (resp.entity)); ? –

+0

Forse potresti ottenere qualcosa in jsFiddle per dimostrarlo? Sarebbe più facile vedere parte del tuo codice. Suppongo che forse stai facendo 'with: selected' nella tua interfaccia utente o usando un template contro' selected'? –

+0

@RomanBataev: Nulla è associato direttamente a vm.selected. In editItem() i dati trasmessi provengono da ItemWrapper nel observableArray. La variabile selezionata punta quindi all'elemento nell'array. Come il punto (2) dimostra che è legato all'interfaccia utente ok quando si passano le proprietà individualmente, ma non quando si passa ItemWrapper nella variabile selected(). – jaffa

risposta

6

OK- il problema è che i cloni finiscono con mappatura meta-dati su di loro e alla fine questo fa sì che la ricorsione quando si cerca di chiamare ko.mapping.fromJS.

La soluzione è creare i cloni utilizzando ko.mapping.toJS anziché ko.toJS, in modo da ottenere un clone pulito (senza mappare i metadati).

Ecco un violino aggiornamento: http://jsfiddle.net/rniemeyer/tDDBp/

+0

Grazie per questo. Non so perché ko.toJS manterrebbe i dati di mappatura e il ko.mapping.toJS no. – jaffa

+0

ko.mapping.toJS conosce in modo specifico le opzioni di mappatura e le rimuove, mentre ko.toJS non ha idea del plugin di mappatura. –

0

Qualcosa ho anche incappato oggi che ho pensato di condividere:

Se si utilizza Clone: ​​

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

Poi il clone sarà spogliato di qualsiasi osservabile calcolato. Esisteranno come ultimo valore della funzione, ma non funzionano più come osservabili calcolati.

Se l'oggetto è un modello complesso con osservabili calcolato che si desidera mantenere sul vostro clone è possibile effettuare le seguenti operazioni:

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

Dove itemModel è il tuo modello complesso per il tuo articolo contenente i osservabili calcolati.

Problemi correlati