Cargando



Bindings avanzados en Knockout.js

En este tutorial veremos cómo crear bindings avanzados en Knockout.js, así como estaremos viendo algunos conceptos relacionados con los mismos, de forma que podamos hacer aplicaciones más grandes y complejas, teniendo código pequeño y controlable.


abr 30 2015 01:48
Profesional
nov 30 2015 20:51

La escritura de aplicaciones complejas va atada al incremento en la complejidad del código, aunque esto suele suceder no es un axioma ni una regla establecida, de hecho lo mejor sería que nuestra aplicación fuese compleja debido a la unión de muchas pequeñas aplicaciones, ya que una pequeña aplicación simple haría que la vida del desarrollador no se complicara tanto.

 

En el caso de Knockout.js ocurre algo similar con los bindings, donde existen comportamientos que podemos lograr utilizando los bindings preestablecidos, sin embargo esto nos generaría una complejidad alta al final ya que esto nos corta un poco de flexibilidad, con esto no decimos que los bindings básicos sean malos, simplemente hay ocasiones en las cuales no nos funcionarían de manera adecuada.

 

Bindings avanzados
Es por ello que debemos emplear los bindings avanzados, aquí podremos construir nuestros propios bindings con comportamientos que definamos directamente, ahorrándonos cierto grado de complejidad en el código y ganando en legibilidad, la única desventaja por así llamarlo es que construiríamos estos comportamientos casi desde cero haciendo que la reutilización de código sea nula.

 

Hacer binding de dos o más ViewModels

Hay ocasiones en las cuales nuestros ViewModels deben permanecer lo más simple posible, o tal vez necesitamos utilizar un ViewModel que es compartido en cada página de nuestra aplicación, en cualquier caso el requerimiento de poder utilizar varios ViewModels a la vez permanece.

 

¿Cómo funciona?
Antes de preocuparnos con este tema, es bueno saber que no es algo descabellado y tampoco imposible de realizar, de hecho es una práctica muy común para mantener la simpleza y la legibilidad de nuestro código en la aplicación. Para hacer esto realidad solamente debemos pasar un segundo parámetro al método ko.applyBindings que nos ayudará a realizar este objetivo al limitar el binding al HTML que lo contiene, de esta forma podremos aplicar todos los ViewModel que necesitemos sin ningún tipo de inconveniente

 

Veamos un pequeño ejemplo donde haremos esto posible, en primer lugar vamos a construir un HTML donde tendremos dos elementos <div> cada uno con un nombre de ViewModel diferente, esto nos dará la base para lo que queremos lograr y dentro de cada input simplemente colocaremos un data-bind del tipo text.

 

Ya en la parte del JavaScript definiremos nuestro ViewModel general donde devolveremos un atributo llamado nombre y al momento de hacer la instancia de los mismos vamos a crear un viewModel1 y un viewModel2 los cuales serán instancias del ViewModel general que creamos usando nombres diferentes, finalmente al aplicarle el ko.applyBinding le diremos a qué bloque HTML debe pertenecer cada uno y así lograremos el objetivo de este ejemplo.

 

Veamos entonces en el siguiente código como expresamos todo lo que hemos explicado anteriormente:

<!DOCTYPE html>
<html lang="es">
<head>
		    <meta charset="UTF-8">
		    <title>Data Binding Avanzado</title>
		   
</head>
<body>
    <div id="viewModel1">
	    <h1 data-bind="text: nombre"></h1>
    </div>
    <div id="viewModel2">
	    <h1 data-bind="text: nombre"></h1>
    </div>

		    <script src="js/knockout-3.3.0.js" type="text/javascript"></script>
		    <script>
		    	 function ViewModel(nombre) {
		    var self = this;
		    self.nombre = nombre;
	    };
	    var viewModel1 = new ViewModel('Jonathan Acosta');
	    ko.applyBindings(viewModel1, document.getElementById('viewModel1'));
	    var viewModel2 = new ViewModel('Miguel Guerrero');
	    ko.applyBindings(viewModel2, document.getElementById('viewModel2'));
		    </script>		
</body>
</html>
Veamos en la siguiente imagen como luce nuestro ejemplo cuando lo ejecutamos en el navegador:

 

 

Vemos en la imagen que nuestros dos ViewModels efectivamente están siendo aplicados en nuestro HTML cada uno contenido en el elemento que pasamos como segundo parámetro al método ko.applyBindings() dándonos así la idea de cómo podemos aplicarlo de forma más completa en nuestras aplicaciones.

 

Bindings y TinyMCE

Para este ejemplo vamos a construir una funcionalidad adaptada al mundo real, vamos a construir un binding avanzado que nos ayude a incorporar el editor TinyMCE en nuestro HTML, este editor lo que hace es construir una interfaz WYSIWYG, es decir, un editor de textos enriquecido. La dificulta principal de esta implementación es que debemos crear nuestro propio binding, lo que nos puede causar un dolor de cabeza si no tenemos una guía adecuada, cosa con la que contaremos ahora.

 

Requisitos
Para poder llevar a cabo este ejemplo tenemos que descargar unos cuantos recursos externos, en este caso jQuery en su última versión, además de descargar el TinyMCE e incluirlo en nuestro proyecto, para conseguir los recursos simplemente tenemos que hacer una búsqueda rápida en Google por lo que no nos detendremos mucho en este punto. Lo otro que necesitaremos es crear un nuevo archivo llamado kobinding.js que es donde escribiremos el código necesario para que nuestra solución pueda funcionar de forma adecuada. Una vez que tenemos todos nuestros recursos descargados y en una ruta a la cual podamos acceder desde nuestra aplicación podemos entonces escribir nuestro código.

 

La aplicación lo que va a hacer es darnos un preview de lo que escribamos, para ello crearemos un formulario donde colocaremos nuestra caja de texto que tendrá al TinyMCE, un botón de reset para devolver todo al estado inicial y finalmente un <div> donde recibiremos el texto que estemos escribiendo.

 

Por último incluiremos todos nuestros recursos incluyendo el nuevo archivo kobinding.js y construimos el código necesario para nuestro ViewModel con un observable que nos permite detectar los cambios en nuestra caja de texto, veamos como luce nuestro código:

<!DOCTYPE html>
<html lang="es">
<head>
		    <meta charset="UTF-8">
		    <title>Data Binding Avanzado TinyMCE</title>
		   
</head>
<body>

    <form>
	    <textarea data-bind="tinymce: htmlText"></textarea>
    </form>

    <button type="button" data-bind="click: resetContenido">Restablecer Contenido</button>

    <h2>Vista Previa</h2>
    <div data-bind="html: htmlText"></div>

    <script type='text/javascript' src='js/jquery.js'></script>
    <script type='text/javascript' src='js/tinymce/jquery.tinymce.min.js'></script>
    <script type='text/javascript' src='js/tinymce/tinymce.min.js'></script>
		    <script src="js/knockout-3.3.0.js" type="text/javascript"></script>
    <script type='text/javascript' src='js/kobinding.js'></script>

		    <script>
		    	  function ViewModel() {
		    var self = this;
		    self.htmlText = ko.observable();
		    self.resetContenido = function() {
			    self.htmlText('');
		    };
	    };
	    var viewModel = new ViewModel();
	    ko.applyBindings(viewModel);
		    </script>		
</body>
</html>
Si nos fijamos en el código y hemos seguido los tutoriales anteriores, notaremos que no hay nada que nos pueda causar dudas, sin embargo si corremos esto en nuestro navegador no va a funcionar de la manera en que hemos explicado y eso es porque necesitamos un binding personalizado en nuestro nuevo archivo.

 

Este nuevo código lo que hace es un enlace entre el comportamiento del TinyMCE y nuestro ViewModel, para ello vamos a crear dos funciones o métodos llamados init y update, para el método init como su nombre sugiere es cuando inicializamos nuestro componente, aquí establecemos el binding del textarea con TinyMCE para que podamos aplicar el observable, adicionalmente definiremos el evento change que es cuando cambia el estado y contenido de nuestra caja de texto, de forma que podamos actualizar el contenido en tiempo real.

 

El otro método o función es update, este se activa cada vez que hay cambios en el elemento enlazado como por ejemplo el botón para reestablecer el contenido, el cual lo que hace es que el mismo se une directamente con lo que nos suministre el observable que habíamos creado anteriormente. Veamos el código final entonces para nuestro kobinding.js:

ko.bindingHandlers.tinymce = {
    init: function (element, valueAccessor, allBindingsAccessor) {
	    var tinymceOptions = { setup: function (editor) {
		    editor.on('change', function (event) {
			    valueAccessor()(event.target.getContent());
		    });
		 }
	    };
	    $( element ).text( valueAccessor()() );
	    setTimeout( function() {
		    $( element ).tinymce(tinymceOptions);
	    }, 0 );
	    ko.utils['domNodeDisposal'].addDisposeCallback( element, function() {
		    $( element ).tinymce().remove();
	    });
    },
    'update': function( element, valueAccessor, allBindings ) {
	    var tinymce = $( element ).tinymce(), value = valueAccessor()();
	    if ( tinymce ) {
		    if ( tinymce.getContent() !== value ) {
			    tinymce.setContent( value );
		    }
	    }
    }
};
Si volvemos a ejecutar nuevamente en nuestro navegador veremos que todo funciona como debería, al momento de escribir y si cambiamos el foco veremos que en nuestra área de vista previa tenemos el contenido como debería verse:

 

 

Con esto pudimos crear un binding avanzado y personalizado que nos ayuda a entender todo lo que podemos lograr con un poco de ingenio y todas las herramientas que nos da Knockout. Casos como el de TinyMCE son muy comunes, ya que este tipo de complementos son muy populares en el desarrollo de aplicaciones web, por lo que es posible que tengamos que aplicar alguna solución similar en algún punto del desarrollo de nuestro proyecto.

 

Con esto hemos finalizado este tutorial, como vemos no es necesario limitarnos a las funciones y métodos preestablecidos en Knockout, por supuesto hay funcionalidades que aún son muy avanzadas para este nivel de conocimiento pero que con la práctica y la investigación pueden lograrse. Lo interesante es que todo esto puede lograrse con un poco de lectura de la documentación oficial de Knockout y también buscando casos de ejemplo que nos sirvan para ilustrarnos y colocarnos en contexto.


¿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