Cargando



Cambios dinámicos con Knockout.js

En este tutorial vamos a ver cómo hacer cambios en las propiedades de los elementos de forma dinámica con Knockout.js, con ello podremos generar mejores interfaces e interacciones de nuestros usuarios con nuestra aplicación.


mar 26 2015 02:13
Profesional
mar 26 2015 10:11
Uno de los aspectos en los cuales se tiene muchos problemas cuando se trabaja en soluciones que no son dinámicas para el cliente es cuando tenemos que hacer cambios de propiedades en tiempo real, por ejemplo si necesitamos refrescar un combo de opciones, si trabajamos solo con tecnología de lado de servidor tendríamos que llevar a refrescar la página para hacer el cambio.

Knockout.js nos evita todos estos problemas al ofrecernos herramientas que podemos utilizar para detectar los cambios que hace el usuario mientras hace uso de nuestra aplicación, de esta manera podemos establecer condiciones, nuevas propiedades y hasta construir elementos que lleven a la aplicación a funcionar de diferentes formas.

El concepto Observable


A pesar que observable suena igual en español y en inglés, el significado no es el mismo aunque están relacionados, en Knockout.js esta palabra se refiere a una serie de métodos y objetos que nos permiten mantener en estado de observación diferentes secciones, elementos o propiedades de nuestro documento HTML.

La idea es que si hacemos la programación correspondiente al mantener bajo observación estos elementos podemos detectar cuando cambien, y si es de nuestra necesidad al haber algún cambio generar una reacción respecto a dicho cambio del elemento. Esto es lo que conocemos también como cambio de propiedades en forma dinámica.

Definición de un Observable


Para definir un objeto o elemento observable dentro de un código en Knockout.js simplemente debemos seguir una estructura como la siguiente:
var nombreDelElemento = ko.observable();
Como vemos es muy simple, sencillamente lo que hacemos es tomar una variable cualquiera y asignarle el método observable(), esto hace que Knockout.js le asigne todas las funcionalidades que corresponden a esta variable.

Luego si queremos manipularla como por ejemplo asignarle un valor, simplemente se lo pasamos como parámetro, veamos el siguiente ejemplo:
var elemento = ko.observable();elemento('Hola Mundo');alert(elemento());
Si nos fijamos hemos definido observable de forma normal, luego lo llamamos como una función y de parámetro le pasamos un valor, en este caso un texto, luego para acceder a su contenido simplemente llamamos a este observable como una función, lo que debe ser suficiente para obtener su contenido de esta manera. Veamos en la siguiente imagen como podemos comprobarlo en nuestro navegador:




Este acercamiento simplista es lo que nos ayudará a entender de buena manera cómo podemos trabajar con este tipo de elementos dentro de nuestra aplicación.

Crear un array Observable


Siguiendo la misma tónica del caso anterior también existe un tipo de observable que es un array, de esta forma podemos almacenar diferentes valores en los índices del elemento que creamos, veamos sin preámbulos como lo definimos:
var elemento = ko.observableArray([]);
Luego si deseamos insertar elementos a dicho elemento simplemente debemos llamar al método o función push() con el contenido que queremos insertar:
elemento.push('Hola Mundo');
Lo importante aquí es que los elementos que estén “suscritos” a los cambios de nuestro observable, inmediatamente tendrán una notificación sobre el cambio que acaba de ocurrir, dándonos así la oportunidad de poder procesar el cambio y dar una respuesta o hacer algún procesamiento en la aplicación.

Combinar Observables
Hay dos formas de hacer que dos o más observables puedan ser combinados y con ello podamos utilizar lógicas más complejas, la primera es el computed observable, y la segunda es el pureComputed observable, esta última se implementó a partir de la versión 3.2 de Knockout.js, por lo que debemos tomar nuestras precauciones dependiendo de la versión que estemos utilizando.

La diferencia entre ambas radica básicamente en el manejo de los recursos y la memoria, donde la última es mucho más eficiente debido a que toma una instancia un poco más pasiva a la hora de comunicar los eventos y los cambios sobre los elementos que se están incorporando a sus “suscritos”. La forma en la que definimos ambas es muy similar y las podemos ver a continuación.

Definir computed observable


Para la primera forma podemos utilizar la siguiente estructura:
self.nombre = ko.observable('Jonathan');self.apellido = ko.observable('Acosta');self.combinado = computed( function() { return 'Hola' + self.nombre() + ' ' + self.apellido();});
Como vemos hemos combinado efectivamente dos observables de forma sencilla.

Definir pureComputed Observable


Ahora veamos cómo podemos definir nuestra segunda forma, notaremos enseguida las similitudes entre ambos, veamos:
self.nombre = ko.observable('Jonathan');self.apellido = ko.observable('Acosta');self.combinado = pureComputed( function() { return 'Hola' + self.nombre() + ' ' + self.apellido();});
Como vemos el único cambio que se sufrió fue el nombre del método que combina a los observables, por lo que ya tenemos dos herramientas dominadas sin mayor dificultad.

Diferencias de ejecución entre computed y pureComputed


Vamos ahora a ver un ejemplo donde vemos la diferencia de gestión de memoria entre ambas formas de combinación de observables, para ello utilizaremos un contador y así nos daremos cuenta de cómo Knockout.js distribuye los recursos y la ejecución, debemos hacer notar que esta prueba es solamente demostrativa y que este código no es recomendado para una aplicación real. Veamos el código de ejemplo:
<!DOCTYPE html><html lang="es"><head> <meta charset="UTF-8"> <title>Nuestro Observable</title> </head><body> <h1>Ejemplo Observable</h1> <script src="js/knockout-3.3.0.js" type="text/javascript"></script> <script> function ViewModel() { var self = this; self.nombre = ko.observable('Jonathan'); self.apellido = ko.observable('Acosta'); self.pureComputedEjecuciones = 0; self.computedEjecuciones = 0; self.pureComputedNombreCompleto = ko.pureComputed(function() { self.pureComputedEjecuciones++; return 'Hola ' + self.nombre() + ' ' + self.apellido(); }); self.computedNombreCompleto = ko.computed(function() { self.computedEjecuciones++; return 'Hola ' + self.nombre() + ' ' + self.apellido(); }); }; var viewModel = new ViewModel(); ko.applyBindings(viewModel); alert('Ejecuciones de pureComputed: ' + viewModel.pureComputedEjecuciones + '\nEjecuciones de Computed: ' + viewModel.computedEjecuciones); </script> </body></html>
El contador que mencionamos lo colocamos justo dentro de la combinación de los observables, así podremos ver que en el caso del pureComputed no se ejecuta nada al inicio a menos que se le observe directamente, en cambio con el otro caso, al menos se ejecuta una vez, tomando una posición más activa resultando en un consumo de recursos mayor, veamos en la imagen como nuestro código se ejecuta y nos confirma lo que hemos explicado.




Mostrar y ocultar elementos


Ya que conocemos un poco la teoría detrás de lo que podemos utilizar en Knockout.js para cambiar propiedades de forma dinámica, vamos a construir un ejemplo donde mostremos y ocultemos un elemento simplemente con la acción del usuario.

Si bien esto puede parecer un poco simplista es muy efectivo porque manejaremos todos los conceptos, desde escuchar un cambio hasta reaccionar y tomar una acción. Veamos el código, luego la explicación.
<!DOCTYPE html><html lang="es"><head> <meta charset="UTF-8"> <title>Nuestro Observable</title> </head><body> <h1>Ejemplo Mostrar y Ocultar</h1> <button type="button" data-bind="click: actualizarVista">Hacer Click!</button> <div data-bind="visible: datosAdicionales" style="display: none"> <p> El contenido dinámico va aquí </p> </div> <script src="js/knockout-3.3.0.js" type="text/javascript"></script> <script> function ViewModel() { var self = this; self.datosAdicionales = ko.observable(false); self.actualizarVista = function() { self.datosAdicionales(!self.datosAdicionales()); }; }; var vistaModelo = new ViewModel(); ko.applyBindings(vistaModelo); </script> </body></html>
El código es muy simple, creamos un pequeño botón que al hacer click sobre él va a llamar a nuestra función actualizarVista, esta lo que hace es que toma el elemento observable datosAdicionales, y le dice que su valor va a ser el contrario del que tenga en el momento, originalmente este valor es false, esto hace que cuando carguemos por primera vez la aplicación el contenido adicional no se vea, al hacer click entonces cambiamos el valor a true y en ese momento sí debería verse. Veamos en la siguiente imagen como luce esto cuando ejecutamos en el navegador:




Antes de hacer click vemos como no hay nada, y nuestro elemento oculto se mantiene con su propiedad display none. Ahora una vez que hacemos click en el botón, notamos como todo cambia rápidamente.




La propiedad display none desaparece y podemos ver el contenido que estaba oculto, todo esto rápidamente y sin tener que reprocesar en nuestra página, haciendo así un cambio dinámico de una propiedad.

Con esto hemos finalizado este tutorial, es muy importante saber que los elementos observable son muy poderosos, sin embargo debemos tener cuidado de no abusar de su uso ya que estos conllevan un procesamiento importante al momento de ser inicializados, es por ello que si no hacemos un uso inteligente podemos terminar haciendo una aplicación que se vuelva lenta con el uso. Cuando pensamos en propiedades dinámicas estamos pensando en experiencia de usuario, en rendimiento y en facilidad de uso, es por ello que debemos entender cuando es factible y cuando no, de esta forma un usuario nos va a agradecer más que la aplicación sea rápida y ágil aunque tenga que recargar un par de veces.

¿Te ayudó este Tutorial?


Sin comentarios, sé el primero!

No esperes más y entra en Solvetic
Deja tus comentarios y aprovecha las ventajas de la cuenta de usuario ¡Únete!

X