Knockout.js ko.mapping.toJS non rinfrescante dati a mio avviso
-
25-10-2019 - |
Domanda
I recuperare un oggetto JSON dal server e popolano mio punto di vista. Ho poi modificare i dati, spingerlo indietro al server. Ho poi prenderti una nuova copia dei dati nella speranza che possa rinfrescarmi la vista con le eventuali modifiche. Tuttavia questo non accade. TIA
$(document).ready(function() {
var customer_id = get_customer_id();
var data = load_model();
contract_model = ko.mapping.fromJS(data,{});
ko.applyBindings(contract_model);
}
function load_model(){
var url = '/ar/contract_json?contract_id='+get_contract_id();
var data = '';
$.ajax({
type:'GET',
url:url,
async:false,
success: function(returningValue){
data = returningValue;
}
});
return data;
}
Questa caricamento iniziale funziona bene. Ho poi fare alcune cose e cambiare una delle osservabili e spingere che di nuovo i dati al server. Server ottiene l'aggiornamento e poi faccio un nuovo recuperare i dati in modo che vista si aggiorna (so che posso passare di nuovo i nuovi dati in un solo passaggio, ma questo nel codice non ho ancora refactoring).
function refresh_data(contract_model){
var url = '/ar/contract_json?contract_id='+get_contract_id();
$.post(url,function(data){
console.log(data);
ko.mapping.fromJS(contract_model,{},data);
ko.applyBindings(contract_model);
console.log(ko.mapping.toJS(contract_model))
});
}
function refresh_data(contract_model){
var url = '/ar/contract_json?contract_id='+get_contract_id();
$.post(url,function(data){
console.log(data);
ko.mapping.fromJS(contract_model,{},data);
console.log(ko.mapping.toJS(contract_model))
});
}
function push_model(contract_model,refresh){
var url = '/ar/update_contract';
var data = {'contract':ko.mapping.toJSON(contract_model)}
delete data['lines'];
$.post(url,data,function(return_value){
if (refresh){
refresh_data(contract_model);
};
});
}
I messaggi della console mostra tutti i nuovi dati che ritornano, ma la mia vista non gli aggiornamenti.
Soluzione
Credo che il problema è con l'ordine dei parametri si passa nella funzione ko.mapping.fromJS
quando si sta aggiornando contract_model
.
Hai:
ko.mapping.fromJS(contract_model,{},data);
che si desidera:
ko.mapping.fromJS(data, {}, contract_model);
Altri suggerimenti
@ di seth.miller risposta è corretta. È anche possibile lasciare il parametro di mezzo "opzioni", se il vostro contract_model
è lo stesso che è stato mappato in precedenza. Se ci sono solo due argomenti, i controlli ko.mapping.fromJS
se il secondo argomento ha una proprietà "__ko_mapping__"
. Se è così, lo tratta come un bersaglio, altrimenti lo tratta come un oggetto opzioni.
Sulla base @ osservazione di DBueno -. Per chiunque utilizzi dattiloscritto Consiglio vivamente commentando questo metodo di firma dal file knockout.mapping.d.ts
// fromJS(jsObject: any, targetOrOptions: any): any;
Sì -. Basta commentare fuori
Si farà quindi ottenere un errore di compilazione se si tenta di fare:
ko.mapping.fromJS(item.data, item.target);
ed è possibile sostituirlo con il molto più sicuro
ko.mapping.fromJS(item.data, {}, item.target);
Safer perché se item.target
è stata precedentemente mappato (e therfore sarebbe avere una proprietà __ko_mapping__
) sarà sempre copiare le proprietà.