tutorial observablearray knockoutjs knockout item mvvm knockout.js data-binding knockout-mapping-plugin

mvvm - observablearray - KnockOutJS-Multiple ViewModels en una sola vista



knockoutjs com observablearray (5)

Estoy pensando que mi aplicación se está volviendo bastante grande ahora, demasiado grande para manejar cada Vista con un único ViewModel.

Así que me pregunto qué tan difícil sería crear múltiples ViewModels y cargarlos en una sola Vista. Con una nota de que también necesito poder pasar los datos de X ViewModel a los datos de Y ViewModel , por lo que los ViewModels individuales deben poder comunicarse entre sí o al menos estar informados entre sí.

Por ejemplo, tengo un menú desplegable <select> , ese menú desplegable de selección tiene un estado seleccionado que me permite pasar el ID del elemento seleccionado en la <select> a otra llamada de Ajax en un ViewModel separado ...

Se agradece cualquier punto al tratar con numerosos ViewModels en una sola Vista :)



Esta es mi respuesta después de completar un proyecto muy grande con muchos ViewModels en una sola vista.

Vista html

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> </head> <body> <div id="container1"> <ul> <li >Container1 item</li> <!-- ko foreach: myItems --> <li>Item <span data-bind="text: $data"></span></li> <!-- /ko --> </ul> </div> <div id="container2"> <ul> <li >Container2 item</li> <!-- ko foreach: myItems --> <li>Item <span data-bind="text: $data"></span></li> <!-- /ko --> </ul> </div> <script src="js/jquery-1.11.1.js"></script> <script src="js/knockout-3.0.0.js"></script> <script src="js/DataFunction.js"></script> <script src="js/Container1ViewModel.js"></script> <script src="js/Container2ViewModel.js"></script> </body> </html>

Para esta vista estoy creando 2 modelos de vista para id = container1 e id = container2 en dos archivos javascript separados.

Container1ViewModel.js

function Container1ViewModel() { var self = this; self.myItems = ko.observableArray(); self.myItems.push("ABC"); self.myItems.push("CDE"); }

Container2ViewModel.js

function Container2ViewModel() { var self = this; self.myItems = ko.observableArray(); self.myItems.push("XYZ"); self.myItems.push("PQR"); }

Luego, después de estos 2 modelos de vista, se registran como modelos de vista separados en DataFunction.js.

var container1VM; var container2VM; $(document).ready(function() { if ($.isEmptyObject(container1VM)) { container1VM = new Container1ViewModel(); ko.applyBindings(container1VM, document.getElementById("container1")); } if ($.isEmptyObject(container2VM)) { container2VM = new Container2ViewModel(); ko.applyBindings(container2VM, document.getElementById("container2")); } });

Así, puedes agregar cualquier número de modelos de vista para divs separados. Pero asegúrese de no crear un modelo de vista separado para un div dentro del div registrado.


Knockout ahora admite el enlace de múltiples modelos. El método ko.applyBindings() toma un parámetro opcional: el elemento y sus descendientes a los que se activará el enlace.

Por ejemplo:

ko.applyBindings(myViewModel, document.getElementById(''someElementId''))

Esto restringe la activación del elemento con ID someElementId y sus descendientes.

Consulte la documentation para más detalles.


Si todos deben estar en la misma página, una forma fácil de hacerlo es tener un modelo de vista maestro que contenga una matriz (o lista de propiedades) de los otros modelos de vista.

masterVM = { vmA : new VmA(), vmB : new VmB(), vmC : new VmC(), }

Entonces su masterVM puede tener otras propiedades si es necesario, para la página en sí. La comunicación entre los modelos de vista no sería difícil en esta situación, ya que podría retransmitirse a través del masterVM , o podría usar $parent / $root en los enlaces, u otras opciones personalizadas.