2012-02-16 10 views
6

Prendo un oggetto JSON dal server e compilo la mia vista. Allora cambio i dati, lo spingo indietro al server. Prendo quindi una nuova copia dei dati sperando che aggiorni la mia vista con qualsiasi modifica. Tuttavia ciò non accade. TIAKnockout.js ko.mapping.toJS non aggiorna i dati nella mia vista

$(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; 
} 

Questo caricamento iniziale funziona correttamente. Quindi faccio delle cose e cambio uno degli osservabili e li rimando al server. Il server ottiene l'aggiornamento e quindi faccio un nuovo recupero dei dati in modo che la vista si aggiorni (so che posso passare i nuovi dati in un solo passaggio ma questo in codice non ho ancora refactored).

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 tutti mostrano i nuovi dati di ritorno, ma la mia vista non aggiorna mai.

risposta

20

Credo che il problema sia con l'ordine dei parametri passati alla funzione ko.mapping.fromJS durante l'aggiornamento di contract_model.

si dispone di:

ko.mapping.fromJS(contract_model,{},data); 

si desidera:

ko.mapping.fromJS(data, {}, contract_model); 
+12

I documenti KnockOut per il plug-in Mapping sono, IMO, errati nella sintassi per la chiamata di ko.mapping.fromJS (...). I documenti mostrano quanto segue: ko.mapping.fromJS (data, viewModel), ma chiaramente questo dovrebbe essere: ko.mapping.fromJS (data, {}, viewModel) –

+1

Ore trascorse su questo. Grazie, questo è stato di grande aiuto. –

+0

Ho anche passato ore su questo. Ti devo un pacchetto di sei – stackoverfloweth

2

@ risposta di seth.miller è corretta. Puoi anche escludere il parametro "Opzioni" intermedio se lo contract_model è lo stesso mappato in precedenza. Se ci sono solo due argomenti, ko.mapping.fromJS controlla se il secondo argomento ha una proprietà "__ko_mapping__". Se è così, lo considera come un obiettivo, altrimenti lo tratta come un oggetto di opzioni.

+0

Ugh questo è stupido. Se il secondo argomento non ha la proprietà "__ko_mapping __" 'e il terzo argomento non esiste, allora dovrebbe trattare il secondo argomento come obiettivo. –

0

Sulla base dell'osservazione di @Barbueno - per chiunque usi dattiloscritto consiglio vivamente di commentare questo particolare sovraccarico dal file knockout.mapping.d.ts.

fromJS(jsObject: any, targetOrOptions: any): any; 

enter image description here

Avrai quindi 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); 

Più sicuro perché è stato precedentemente mappato item.target (e quindi sarebbe h ava una proprietà __ko_mapping__) copierà sempre le proprietà.

Problemi correlati