2011-01-21 6 views
9

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).Observando las propiedades de una matriz que se está observando en KnockoutJS

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

Quiero observar esta matriz, por lo que cada vez que cambia puedo actualizar una tabla que se ha unido a una plantilla.

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

Esto funciona muy 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 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.

que hemos probado algo como esto con vano:

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 mesa si es necesario.

Respuesta

4

Usted debe mirar en el knockout.mapping plugin. Creo que hace todo lo que estás buscando hacer.

+0

Definitivamente me perdí ese plugin de alguna manera. Gracias por el aviso, ¡Serge! – harryfino

+0

URL actualizada: http://knockoutjs.com/documentation/plugins-mapping.html –

4

Terminé haciendo que esto funcione, así que pensé que podría compartirlo con cualquiera que pueda tener el mismo problema.

Debe envolver sus elementos de matriz en una clase de JavaScript. A continuación, en el constructor, establezca cada propiedad para 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 artículos directamente a ver el cambio, usted podría hacer algo como:

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

y se puede todavía ser notificado cuando se agregan elementos o eliminar:

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

¿Qué quiere decir por '@ Model.ToJson()'? ¿Su modelo tiene el método ToJson? Gracias –

0

Aquí hay otro método que funciona y que 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); 
Cuestiones relacionadas