Hemos visto cómo las propiedades observables permiten a Knockout.js actualizar automáticamente los elementos HTML cuando se modifican los datos subyacentes, pero esto es solo el comienzo de su utilidad. Knockout.js también viene con dos formas más de exponer las propiedades de ViewModel: observables computados y arreglos observables. Juntos, abren todo un nuevo mundo de posibilidades para las interfaces de usuario basadas en datos..
Observables computados Le permite crear propiedades que se generan dinámicamente. Esto significa que puede combinar varios observables normales en una sola propiedad, y Knockout.js seguirá manteniendo la vista actualizada cada vez que cambie alguno de los valores subyacentes..
Figura 12: un observable calculado que depende de dos observables normales
Matrices observables combina el poder de los observables de Knockout.js con matrices de JavaScript nativas. Al igual que los arreglos nativos, contienen listas de elementos que puede manipular. Pero como son observables, Knockout.js actualiza automáticamente cualquier elemento HTML asociado cada vez que se agregan o eliminan elementos..
Figura 13: una matriz observable que contiene otros ViewModels
La capacidad de combinar elementos observables, junto con la capacidad de trabajar con listas de elementos, proporciona todas las estructuras de datos que necesitará en un ViewModel. Esta lección presenta ambos temas con una sencilla interfaz de carrito de compras..
Observables calculados
Primero, comenzaremos con un simple observable computado. Debajo de la nombre de pila y apellido observables en PersonViewModel, cree el FullName computable observable:
Esto define una función anónima que devuelve el nombre completo de la persona siempre que PersonViewModel.fullName se accede. Generando dinámicamente el nombre completo de los componentes existentes (nombre de pila y lastName) nos impide almacenar datos redundantes, pero eso es solo la mitad de la batalla. Necesitamos pasar esta función a ko.computed () para crear un observable computado. Esto le dice a Knockout.js que necesita actualizar cualquier elemento HTML vinculado a la propiedad fullName siempre que cambien el nombre o el apellido.
Asegurémonos de que nuestros trabajos observables computados unen la línea "Carrito de compras de John" a nombre completo en lugar de primer nombre:
carrito de compras
Ahora su página debería leer "Carrito de compras de John Smith". A continuación, asegurémonos de que Knockout.js mantenga este elemento HTML sincronizado cuando cambiemos una de las propiedades subyacentes. Después de enlazar una instancia de PersonViewModel, intente cambiar su propiedad FirstName:
var vm = new PersonViewModel (); ko.applyBindings (vm); vm.firstName ("Mary");
Esto debería cambiar la línea a "Carrito de compras de Mary Smith". Nuevamente, recuerde que la lectura o el establecimiento de observables deben realizarse con llamadas a funciones, no con la asignación (=) operador.
Los observables computados brindan muchos de los mismos beneficios que la sincronización automática de la vista de Knockout.js. En lugar de tener que hacer un seguimiento de qué propiedades se basan en otras partes de ViewModel, los observables computados le permiten crear su aplicación alrededor de propiedades atómicas y delegar el seguimiento de dependencias a Knockout.js.
Matrices observables
Las matrices observables permiten a Knockout.js rastrear listas de elementos. Exploraremos esto creando una página de visualización de carrito de compras para nuestro usuario. Primero, necesitamos crear un objeto personalizado para representar productos. En la parte superior de nuestro script, antes de definir PersonViewModel, agregue la siguiente definición de objeto:
Esto es solo un objeto de datos simple para almacenar algunas propiedades. Tenga en cuenta que es posible dar múltiples propiedades observables de objetos, y Knockout.js administrará todas las interdependencias por sí solo. En otras palabras, es posible crear relaciones entre múltiple ViewModels en una sola aplicación.
A continuación, vamos a crear algunos ejemplos de nuestro nuevo Producto Clase y agregarlos al carrito de compras virtual del usuario. Dentro de PersonViewModel, Definir una nueva propiedad observable llamada shoppingCart:
this.shoppingCart = ko.observableArray ([nuevo producto ("Beer", 10.99), nuevo producto ("Brats", 7.99), nuevo producto ("Buns", 1.49)]);
Esta es una matriz de JavaScript nativa que contiene tres productos envueltos en una matriz observable para que Knockout.js pueda realizar un seguimiento cuando se agregan y eliminan elementos. Pero, antes de comenzar a manipular los objetos, actualicemos nuestra vista para que podamos ver el contenido de los objetos. carrito de compras propiedad. Debajo de la
etiqueta, agregue lo siguiente:
Producto
Precio
Esta es una tabla HTML 5 típica que contiene una columna para nombres de productos y otra para precios de productos. Este ejemplo también introduce un nuevo enlace llamado para cada. Cuando Knockout.js encuentra foreach: shoppingCart, recorre cada elemento en el ViewModel's carrito de compras propiedad. Cualquier marca dentro del bucle se evalúa en el contexto de cada elemento, por lo que text: name en realidad se refiere a shoppingCart [i] .name. El resultado es una tabla de artículos junto a sus precios:
Figura 14: Captura de pantalla de la lista de productos renderizados
Los detalles de la para cada Los enlaces están fuera del alcance de esta lección. La siguiente lección proporciona una discusión detallada de foreach, y también presenta otros enlaces de control-flujo de Knockout.js. Por ahora, volvamos a los arreglos observables..
Agregando Articulos
El objetivo de usar matrices observables es permitir que Knockout.js sincronice la vista cada vez que agregamos o eliminamos elementos. Por ejemplo, podemos definir un método en nuestro ViewModel que agrega un nuevo elemento, así:
Luego, podemos crear un botón para llamar al método para poder agregar elementos en el tiempo de ejecución y ver que Knockout.js mantenga la lista actualizada. Junto al botón de pago en el código de vista, agregue lo siguiente:
Cuando haces clic en este botón, el ViewModel Añadir Producto() se ejecuta el metodo Y desde carrito de compras es una matriz observable, Knockout.js inserta otra
elemento para mostrar el nuevo elemento. Dejar que Knockout.js haga un seguimiento de los elementos de la lista de este tipo es mucho menos propenso a errores que intentar actualizar manualmente el
cada vez que cambiamos la matriz subyacente.
También vale la pena señalar que Knockout.js siempre hace el mínimo Cantidad de cambios necesarios para sincronizar la interfaz de usuario. En lugar de regenerar la lista completa cada vez que se agrega o elimina un elemento, Knockout.js realiza un seguimiento de las partes del DOM que se ven afectadas y se actualiza. solamente esos elementos Esta optimización incorporada hace posible ampliar su aplicación a cientos o incluso miles de elementos sin sacrificar la capacidad de respuesta.
Eliminar elementos
Del mismo modo, Knockout.js también puede eliminar elementos de una matriz observable a través de retirar() método. Dentro de la definición de PersonViewModel, agregue otro método para eliminar elementos:
this.removeProduct = function (product) this.shoppingCart.remove (product); ;
A continuación, agregue un botón de eliminación para cada elemento en el lazo:
Porque estamos en el para cada contexto, tuvimos que usar el $ raíz referencia para acceder a nuestro ViewModel en lugar del elemento actual en el bucle. Si intentáramos llamar a removeProduct () sin esta referencia, Knockout.js habría intentado llamar al método en la clase Product, que no existe. Todos los contextos de enlace disponibles para foreach se tratan en la siguiente lección.
El hecho de que estemos en una para cada bucle también desordena el esta referencia en removeProduct (), por lo que haga clic en una retirar botón realmente lanzará un TypeError. Podemos usar un truco común de JavaScript para resolver este tipo de problemas de alcance. En la parte superior de la definición de PersonViewModel, asigne esto a una nueva variable llamada self:
función PersonViewModel () var self = this;…
Entonces, use yo en lugar de esta en el método removeProduct ():
this.removeProduct = function (product) self.shoppingCart.remove (product); ;
Ahora debería poder manipular nuestra matriz observable con el Añadir cerveza y retirar botones. También tenga en cuenta que Knockout.js agrega automáticamente el elemento actual en el bucle como primer parámetro a removeProduct ().
Destruyendo objetos
los retirar() El método es útil para la manipulación de listas en tiempo real, pero puede resultar problemático una vez que empiezas a intentar enviar datos desde ViewModel a un script del lado del servidor..
Por ejemplo, considere la tarea de guardar el carrito de la compra en una base de datos cada vez que el usuario agregue o elimine un artículo. Con retirar(), el elemento es eliminado inmediatamente, así que todo lo que puede hacer es enviar a su servidor la nueva lista en su totalidad; es imposible determinar qué elementos se agregaron o eliminaron. Debe guardar la lista completa o descifrar manualmente la diferencia entre la versión anterior almacenada en la base de datos y la nueva aprobada desde la solicitud de AJAX..
Ninguna de estas opciones es particularmente eficiente, especialmente teniendo en cuenta que Knockout.js sabe con precisión qué elementos se eliminaron. Para remediar esta situación, las matrices observables incluyen una destruir() método. Intente cambiar PersonViewModel.removeProduct () a lo siguiente:
Ahora cuando haces clic en el retirar botón, Knockout.js no lo hará eliminar el elemento de la matriz subyacente. Esto se muestra en el mensaje de alerta, que debería no disminuir al hacer clic en "Eliminar". En lugar de modificar la lista, destruir() método agrega un _destruir Propiedad del producto y lo establece en true. Puede mostrar esta propiedad agregando otro mensaje de alerta:
alerta (product._destroy);
los _destruir La propiedad permite ordenar una lista observable y extraer solo los elementos que se han eliminado. Entonces, puedes enviar solamente esos elementos a un script del lado del servidor para ser eliminado. Esta es una forma mucho más eficiente de administrar listas cuando se trabaja con solicitudes AJAX.
Tenga en cuenta que el para cada bucle es consciente de esta convención, y todavía elimina el asociado
elemento de la vista, aunque el elemento permanezca en la matriz subyacente.
Otros métodos de matriz
Internamente, las matrices observables son como las propiedades observables normales, excepto que están respaldadas por una matriz de JavaScript nativa en lugar de una cadena, número u objeto. Al igual que los observables normales, puede acceder al valor subyacente llamando a la matriz observable sin ninguna propiedad:
this.debugItems = function () var message = ""; var nativeArray = this.shoppingCart (); para (var i = 0; i
Llamar a este método recorrerá los elementos de la lista nativa y también proporcionará acceso a los métodos de la matriz de JavaScript nativa, como empujar(), popular(), shift (), sort (), etc.
Sin embargo, Knockout.js define su propio Versiones de estos métodos en el objeto matriz observable. Por ejemplo, anteriormente en esta lección, usamos shoppingCart.push () para agregar un elemento en lugar de shoppingCart (). push (). El primero llama a la versión de Knockout.js y el último llama a push () en la matriz de JavaScript nativa.
Por lo general, es una idea mucho mejor usar los métodos de matriz de Knockout.js en lugar de acceder directamente a la matriz subyacente porque permite que Knockout.js actualice automáticamente los componentes de vista dependientes. La lista completa de métodos de matriz observable proporcionada por Knockout.js a continuación. La mayoría de estos actúan exactamente igual que sus homólogos nativos de JavaScript.
empujar()
popular()
sin cambios()
cambio()
rebanada()
retirar()
eliminar todo()
destruir()
destruye todo()
ordenar()
invertido()
índice de()
Resumen
En esta lección, vimos cómo se pueden usar los observables computados para combinar observables normales en propiedades compuestas que Knockout.js puede rastrear. También trabajamos con matrices observables, que son una manera de que Knockout.js sincronice las listas de datos en el ViewModel con los componentes HTML..
Juntos, los observables atómicos, computados y de matriz proporcionan todos los tipos de datos subyacentes que necesitará para una interfaz de usuario típica. Los observables calculados y las matrices observables hacen de Knockout.js una excelente opción para la creación rápida de prototipos. Le permiten ubicar todas sus funciones complejas en un lugar y luego dejan que Knockout.js se encargue del resto..
Por ejemplo, sería trivial crear un observable computado que calcule el precio total de cada artículo en el carrito de compras Lista y lo muestra en la parte inferior de la página. Una vez que creas esa funcionalidad, puedes reutilizarla. en cualquier sitio necesita el precio total (por ejemplo, una solicitud AJAX) simplemente accediendo a una propiedad de ViewModel.
La siguiente lección introduce los enlaces de control-flujo. los para cada El enlace que usamos en esta lección es probablemente la herramienta de control-flujo más común, pero Knockout.js también incluye algunos enlaces más para un control preciso sobre nuestros componentes de vista HTML.
Esta lección representa un capítulo de Nocaut sucintamente, un libro electrónico gratuito del equipo en Syncfusion.