2012-04-01 18 views
12

Sto tentando di stabilire una griglia e aggiornarla con altri record tramite JSON. In questo semplice esempio sono in grado di ottenere la funzionalità richiesta, ma posso solo aggiornare/spingere un record JSON. Mi piacerebbe poter aggiungere più record tramite JSON? Come potrei ottenere questo? Ho pensato che avrei dovuto creare una sorta di ciclo for e spingere ogni risultato JSON all'osservabile, ma speravo che knockout potesse avere un modo migliore di aggiornare/analizzare tramite JSON?Aggiornamento Knockout.js osservabile da JSON

Heres una copia di quello che ho ottenuto finora: http://jsfiddle.net/sparkhill/crSbt/

 function Users(user_id, password) { 
    this.user_id = ko.observable(); 
    this.password = ko.observable(); 
} 

var viewModel = { 

    users: ko.observableArray([]), 


    addUser: function() { 
     this.users.push({ 

      user_id: "", 
      password: "" 
     }); 
    }, 

    addJSON: function() { 


     //Works Fine 
     var JSONdataFromServer 
     ='{"user_id":"frances","password":"password"}'; 

     //More than one result - wont map - Would Ideally like to map lots of records at one time 
//var JSONdataFromServer ='{"user_id":"frances","password":"password"}, {"user_id":"frances","password":"password"}'; 

     var dataFromServer = ko.utils.parseJson(JSONdataFromServer); 


     this.users.push(dataFromServer); 

     //Tried 
     //this.users.push(JSON.parse(JSONdataFromServer)); 


    } 

}; 

viewModel.users(); 
ko.applyBindings(viewModel); 

    </script> 

Aggiornamento questo sembra funzionare, ma mi chiedo se il loro è un metodo più efficiente?

addJSON: function() { 

     //Works Fine 
     var JSONdataFromServer 
     ='[{"user_id":"frances","password":"password"},{"user_id":"timmy","password":"password"}]'; 

     var results = JSON.parse(JSONdataFromServer); 

     var i = results.length; 

     for(var i = 0; i < results.length; i++){ 

      this.users.push(results[i]); 
     }; 

risposta

22

Qui ci sono 3 modi si potrebbe fare questo ... trovato in questo violino: http://jsfiddle.net/johnpapa/nfnbD/

1) Usare il ko .utils.arrayPushTutti la funzione 2) usa la tua logica 3) Scrivi la tua funzione su observableArray

Dettagli ...

1) Se si utilizza la funzione ko.utils.arrayPushAll sarà necessario chiamare valueHasMutated troppo, perché la matrice in modo efficace viene sovrascritto con se stesso. L'osservabilità non spara a nulla, tu dici che è cambiato. Ecco come si potrebbe fare:

ko.utils.arrayPushAll(this.users(), dataFromServer); 
this.users.valueHasMutated(); 

2) La seconda opzione è quella di scrivere la propria logica ciclo, in sostanza, utilizzando lo stesso codice della funzione arrayPushAll come questo.

for (var i = 0, j = dataFromServer.length; i < j; i++) 
this.users.push(dataFromServer[i]); 

3) creare una funzione del proprio sulla observableArray, in questo modo:

ko.observableArray.fn.pushAll = function(valuesToPush) { 
     var items = this; 
     for (var i = 0, j = valuesToPush.length; i < j; i++){ 
      items.push(valuesToPush[i]); 
     } 
     return items; 
}; 

Anche se questo codice di cui sopra informerà ogni volta che viene aggiunto un elemento. Quindi potrebbe essere meglio aggiungerli tutti, quindi avvisare. Questo sarebbe più efficiente. Come questo:

ko.observableArray.fn.pushAll = function(valuesToPush) { 
    var underlyingArray = this(); 
    this.valueWillMutate(); 
    ko.utils.arrayPushAll(underlyingArray, valuesToPush); 
    this.valueHasMutated(); 
    return this; 
}; 

quindi chiamare in questo modo:

this.users.pushAll(dataFromServer); 
+0

Ricorda che potresti aver bisogno di creare una variabile di istanza del tuo modello se vuoi aggiornare il tuo observableArray da qualche parte nella tua pagina, al di fuori del modello stesso, ad esempio: 'var myModelInstance = new ViewModel();' ' ko.utils.arrayPushAll (myModelInstance.users(), dataFromServer);' ' myModelInstance.users.pushall –

+1

è ancora la strada da percorrere con la versione 3.1? – Homer

+0

Chiedo la stessa domanda di Omero. 'PushAll' è già nel nucleo di KnockoutJs dalla versione 3.1. – Samuel

3

È possibile utilizzare il plug-in mapping

Vedi http://knockoutjs.com/documentation/plugins-mapping.html

+0

come fa aiuto mappatura plugin con il problema? –

+0

Vedere la sezione "Uso avanzato" (disponibile nell'articolo collegato). Con il plugin puoi personalizzare il processo di aggiornamento/creazione –

1

So che questo è piuttosto un vecchio post, ma mi sono imbattuto in essa e solo pensato che avrei mostrato un altro modo per fare questo in eliminazione diretta senza creare il tuo pushAll per i futuri visitatori.

È possibile utilizzare un push.apply in un sistema ad eliminazione diretta su un array osservabile. Ciò ti consentirà di inviare più elementi da un server e attivare solo una notifica.

Example in JsFiddle

Edit: Il further reading per chiunque la lettura di questo che vuole sapere il motivo per cui utilizzare push.apply invece di utilizzare push in un ciclo

Problemi correlati