knockoutjs knockout event data knockout.js knockout-mapping-plugin

knockout.js - data - knockoutjs event binding



knockout crea un objeto vacĂ­o desde auto-mapeado observable (2)

Estoy tratando de resolver un pequeño problema con el mapeo de ko. El escenario es que mi ViewModel es básicamente una colección de objetos. Cada uno de los objetos se crea a partir de una llamada json, de esta manera:

var ViewModel = ko.observableArray(); $.getJSON(url, function(data) { ViewModel.push(ko.mapping.fromJSON(data)); });

Esto funciona perfectamente y puedo hacer todo tipo de magia en mi HTML. La pregunta es si, por ejemplo, quiero agregar algo a mi colección, supongamos que es compatible con el escenario "Agregar y Editar" del lado del cliente. Me gustaría hacer algo como:

<input type="button" value="add new" data-bind="click: AddNew" />

Y me gustaría que la función AddNew en ViewModel sea algo así como:

function AddNew() { this.push(// WHAT HERE?); }

Básicamente necesito empujar un objeto que es idéntico al otro ya existente, pero por supuesto con todas las propiedades en blanco ...

Estaba pensando en una forma de "clonar" un objeto de la lista y configurar todos los observables para que se vayan, pero no sé por dónde empezar, me temo:


¿Conoces los campos o los necesitas copiados de lo que obtienes del servidor? Creo que tendrías problemas para comenzar una nueva lista si ese fuera el caso. Podrías simplemente crear una plantilla y presionarla:

var myTemplate = { name: ko.observable(), phone: ko.observable() }; ViewModel.push(myTemplate); // add empty item

Nunca he visto el modelo de vista como una matriz observable u observable, ¿por qué no crearlo así?

function ViewModel() { self = this; self.items = ko.observableArray(); } var myViewModel = new ViewModel(); ko.applyBindings(myViewModel); $.getJSON(url, function(data) { myViewModel.items.push(ko.mapping.fromJSON(data)); });


Si vas a expandir tu funcionalidad a editar / agregar desde el lado del cliente, te recomendaría formalizar tus objetos en una clase js y luego mapearlos internamente. Esto le permitiría tener sus métodos de agregar en su modelo de vista principal y crear instancias en blanco del lado del cliente fácilmente.

Una advertencia con el plugin de mapeo es que para actualizar objetos se espera que esos objetos hayan sido mapeados originalmente por el plugin. Aquí hay un ejemplo rápido de cómo se podría hacer.

var YourObjectClass = function (config) { var self = this, data; // your default structure goes here data = $.extend({ name: "", id : -1 }, config); ko.mapping.fromJS(data, {}, self); }; var viewModel = function(initialData) { var self = this; ko.mapping.fromJS(initialData, { items: { create : function (options) { return new YourObjectClass(options.data); } } }, self); this.AddNew = function () { self.items.push(new YourObjectClass()); } };

Espero que esto ayude.