2012-04-01 17 views
12

Intento establecer una grilla y actualizarla con más registros a través de JSON. En este sencillo ejemplo, puedo lograr la funcionalidad requerida pero solo puedo actualizar/presionar un registro JSON. Me gustaría poder agregar varios registros a través de JSON? ¿Cómo podría lograr esto? Supuse que tendría que crear algún tipo de bucle y empujar cada resultado JSON a lo observable, pero esperaba que el nocaut pudiera tener una mejor forma de actualizar/analizar a través de JSON.Update Knockout.js Observable from JSON

Aquí está una copia de lo que he conseguido hasta ahora: 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> 

Actualización esto parece funcionar, pero me pregunto si su es un método más eficiente?

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]); 
     }; 

Respuesta

22

Aquí hay 3 formas en que podría hacer esto ... se encuentran en este violín: http://jsfiddle.net/johnpapa/nfnbD/

1) Utilice el ko .utils.arrayPushAll function 2) use su propia lógica 3) Escriba su propia función en observableArray

Detalles ...

1) Si se utiliza la función ko.utils.arrayPushAll tendrá que llamar valueHasMutated también, porque la matriz efectivamente se sobreescribe con la misma. La observabilidad no se dispara siempre que le digas que ha cambiado. Aquí es cómo se puede hacer eso:

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

2) La segunda opción es escribir su propia lógica de bucle, usando esencialmente el mismo código que la función arrayPushAll como este.

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

3) Crear una función de su propia en el observableArray, así:

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

Aunque este código notificará cada vez que se agrega un elemento. Entonces, sería mejor agregarlos todos, luego notificar. Esto sería más eficiente. De esta manera:

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

Entonces llaman así:

this.users.pushAll(dataFromServer); 
+0

tenga en cuenta que puede necesitar crear una variable de instancia de su modelo si desea actualizar su array observable desde algún lugar de su página, fuera del modelo real en sí, por ejemplo: 'myModelInstance var = nuevo modelo de vista();' ' ko.utils.arrayPushAll (myModelInstance.users(), dataFromServer);' ' myModelInstance.users.pushall –

+1

¿sigue siendo el camino a seguir con la versión 3.1? – Homer

+0

Hago la misma pregunta que Homer. Es 'pushAll' ya en el núcleo de KnockoutJs desde la versión 3.1. – Samuel

3

Puede utilizar el plug-in mapping

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

+0

¿Cómo ayuda la asignación plugin con el problema? –

+0

Consulte la sección "Uso avanzado" (que está disponible en el artículo vinculado). Con el complemento puede personalizar el proceso de actualización/creación –

1

Sé que esto es bastante una entrada antigua, pero me encontré con él y sólo pensé en mostrar otra forma de hacer esto en octavos sin crear su propio pushAll para futuros visitantes.

Puede usar un push.apply en un knockout en una matriz observable. Esto le permitirá enviar múltiples elementos desde un servidor y solo disparar una notificación.

Example in JsFiddle

Editar: El further reading para cualquiera que lea esto que quiere saber por qué utilizar push.apply en lugar de utilizar push en un bucle

Cuestiones relacionadas