knockoutjs knockout data model-view-controller templates knockout.js observable

model view controller - data - Observando las propiedades de una matriz que se está observando en KnockoutJS



ko observable (3)

Estoy trabajando en una aplicación ASP.Net MVC. Mi acción es devolver una vista con un modelo que es una matriz de objetos (una clase con propiedades como Nombre, ID, IsViewable).

var model = @Model.ToJson(); // done via extension call

Quiero observar esta matriz, por lo que cada vez que cambie puedo actualizar una tabla que se vinculó a una plantilla.

var viewModel = { accounts = ko.observableArray(model) }

Esto funciona bien para agregar y eliminar elementos de la matriz. Sin embargo, también quiero que la plantilla se actualice cuando cambia una propiedad en una de las cuentas (es decir, nombre o ID).

En el sitio web de KnockoutJS, dice: Por supuesto, puede hacer que esas propiedades sean observables si lo desea, pero esa es una opción independiente . Esto es lo que no puedo descifrar cómo hacerlo.

Intenté algo así sin éxito:

var viewModel = { accounts = ko.oservableArray([]) } for(var i = 0; i < model.length; i++) { ko.observableArray(model[i]); viewModel.accounts.push(model[i]); }

Puedo publicar la plantilla y la tabla si es necesario.


Terminé haciendo que esto funcionara, así que pensé que podría compartirlo con cualquiera que tenga el mismo problema.

Debe envolver sus elementos de matriz en una clase de JavaScript. Luego, en el constructor, establece cada propiedad en obserable:

var model = @Model.ToJson(); var viewModel = { accounts = ko.observableArray(ko.utils.arrayMap(model, function(account) { return new AccountWrapper(account); })) }; function AccountWrapper(account) { this.Property1 = ko.observable(account.Propery1); this.Property2 = ko.observable(account.Propery2); this.Property3 = ko.observable(account.Propery3); } ko.applyBindings(viewModel);

Y si desea modificar uno de los elementos directamente para ver el cambio, podría hacer algo como:

viewModel.accounts()[3].Name(''My Name Changed'');

Y aún puede recibir una notificación cuando se agreguen o eliminen elementos:

viewModel.accounts.remove(viewModel.accounts()[4]);


Aquí hay otro enfoque que funciona y no requiere el plugin de mapeo:

var model = @Model.ToJson(); var viewModel = { accounts: ko.observableArray([]), fromJS: function(js) { for (var i = 0; i < js.length; i++) { this.accounts.push({ Property1: ko.observable(js[i].Property1), Property2: ko.observable(js[i].Property2), Property3: ko.observable(js[i].Property3) }); } } }; viewModel.fromJS(model); ko.applyBindings(viewModel);


Deberías mirar el plugin knockout.mapping . Creo que hace todo lo que estás buscando hacer.