Cargando



Accediendo a data externa con Knockout.js

En este tutorial utilizaremos Knockout.js para leer y guardar información utilizando un formato estándar como lo es el JSON, usando métodos transparentes sin importar el lenguaje del lado del servidor que estemos utilizando.


may 22 2015 03:24
Profesional
ago 22 2016 16:08

Para la mayoría de las aplicaciones web el hecho de poder recolectar el input de los usuarios a través de los formularios es su función principal, pero esto puede quedar de un lado si la aplicación como tal no puede enviar o recibir la data al servidor.

 

Es por ello que existen los lenguajes del lado del servidor o el procesamiento de un JSON para ayudarnos en esta tarea, donde para efectos de este tutorial utilizaremos jQuery como framework de JavaScript para realizar el procesamiento de un JSON, el cual servirá para reemplazar el lenguaje del lado del servidor y nos proporcionará una entrada de datos para ser procesado en nuestro modelo.

 

 

Requisitos


Necesitaremos tener Knockout.js en nuestro sistema y accesible para las aplicaciones que vamos a crear, además necesitamos jQuery el cual podemos utilizarlo de manera local o desde su CDN. Permisos para escribir archivos, una conexión a Internet para obtener las librerías si no las tenemos, y un editor de textos como Sublime Text o NotePad ++. Para ejecutar las aplicaciones necesitamos un servidor web tipo Apache o Nginx en nuestro ambiente de pruebas.

 

Empezaremos a trabajar en la aplicación directamente y no profundizaremos en algunos de los conceptos utilizados en los ejemplos, por lo que recomendamos darnos un paseo por los tutoriales que implican los cambios dinámicos, el manejo de formularios y por supuesto los bindings con Knockout.js.

 

 

Lectura de data externa


Vamos a crear un documento HTML sencillo que tendrá la inclusión de la librería de Knockout.js así como de jQuery. Crearemos nuestro formulario sin olvidarnos de hacer los bindings de los elementos en el mismo y por último en la lógica para nuestra VistaModelo crearemos la función para manejar los cambios en nuestro formulario con los observables, veamos el código para nuestro HTML:
<html lang='en'>
<head> <title>Data Externa</title>
			    <meta charset='utf-8' />
</head>
<body>

<h1>Accediendo a data externa</h1>
<form action="#" method="post">
			    <p>Nombre completo: <input data-bind='value: nombre' /></p>
			    <p>Apellido: <input data-bind='value: apellido' /></p>

<div>
			    Actividades preferidas:
			    <select data-bind='options: actividades, value: hobbies'></select>
</div>
<p><button data-bind='click: cargarDataUsuario'>Cargar data</button></p>
</form>

<script src="js/knockout-3.3.0.js" type="text/javascript"></script>
<script src="//oss.maxcdn.com/jquery/1.11.1/jquery.min.js"></script>
<script type='text/javascript'>

function UsuarioViewModel() {
			    var self = this;
			    self.nombre = ko.observable("");
			    self.apellido = ko.observable("");
			    self.actividades = ko.observableArray([]);
			    self.hobbies = ko.observable("");

}

 ko.applyBindings(new UsuarioViewModel());
</script>
</body>
</html>
Como vemos tenemos un documento HTML sencillo con unos cuantos elementos, comprendidos de dos campos texto y una lista de selección, y si somos observadores podemos ver que nuestros observables están vacíos por igual, para finalizar veamos como luce nuestro formulario inicial:

 

data-externa-knockout.jpg

 

Ya que tenemos nuestro formulario debemos darle sentido a nuestro ejemplo y es el poder cargar data externa en nuestra aplicación, es por ello que nuestros observables se encuentran vacíos. Vamos a valernos del método de jQuery llamado $.getJSON() el cual recibe un JSON como entrada, para el caso que estuviésemos trabajando con un lenguaje del lado del servidor debemos especificar la ruta del archivo que generará el mismo como salida de la siguiente forma:

self.cargarDataUsuario = function() {
$.getJSON("/obtener-data-usuario", function(data) {
			    alert(data.nombre);
});
}
Para no complicar las cosas vamos a utilizar un JSON ya generado dentro de nuestra aplicación, para ello creamos uno con la siguiente estructura el cual pueden variar sus valores si así lo desean:
{"nombre":"Nombre",
 "apellido":"Apellido",
  "actividades":[
			     "Bicicleta",
			     "Videojuegos",
			     "Desarrollo Web"],
  "hobbies":"Leer"
}
Ahora podemos cambiar nuestra función anterior y enviarle como parámetro el nombre de nuestro archivo JSON, veamos:
self.cargarDataUsuario = function() {

$.getJSON("informacion_usuario.json", function(data) {
			    alert(data.nombre);
});
}
Al incluir esta función en nuestro código podremos verificar como funciona nuestro método $.getJSON() y así obtener uno de los valores dentro del mismo, la respuesta de nuestra aplicación al presionar el botón Cargar data, será simplemente mostrando el nombre.

 

Como vemos nuestro método funciona perfectamente, ahora solo debemos luego de obtener los valores de nuestro JSON es incluir la función dentro de nuestra VistaModelo y hacer la correspondencia con los identificadores de nuestro formulario, veamos como luce nuestro código final:

function UsuarioViewModel() {
			    var self = this;
			    self.nombre = ko.observable("");
			    self.apellido = ko.observable("");
			    self.actividades = ko.observableArray([]);
			    self.hobbies = ko.observable("");


self.cargarDataUsuario = function() {
 $.getJSON("informacion_usuario.json", function(data) {

			    self.nombre(data.nombre);
			    self.apellido(data.apellido);
			    self.actividades(data.actividades);
			    self.hobbies(data.hobbies);

});
}

}

 ko.applyBindings(new UsuarioViewModel());
Ahora solo nos queda ejecutar nuestro ejemplo en el navegador y pulsar el botón de Cargar data el cual debe llenar los campos de nuestro formulario de manera inmediata con los valores del JSON, veamos:

 

data-externa.jpg

 

Como vemos funciono de manera perfecta y pudimos leer data externa en unas simples líneas de código. Esto es bastante útil en términos de usabilidad y funcionalidad de nuestra aplicación pero podemos hacer un poco más, podemos almacenar la data en un JSON y así extender la funcionalidad de nuestra aplicación.

 

 

Almacenando la data


Para las aplicaciones web convencionales almacenar la data en formato JSON es tan simple como convertir objetos a ese formato y enviarlos al servidor pero para el caso de las aplicaciones que usan Knockout.js el tema es un poco más complicado ya que la VistaModelo usa observables en vez de propiedades normales de JavaScript, ya que los observables son funciones y tratar de serializar las mismas y enviarlas al servidor puede ocasionar resultados inesperados.

 

ko.toJSON()
Para estos casos estamos de suerte, ya que Knockout.js proporciona una solución simple y efectiva, la función ko.toJSON(), la cual reemplaza todos las propiedades de los objetos observables por su valor actual y retorna el resultado como un string en formato JSON.

 

Para implementar esta nueva funcionalidad en nuestra aplicación vamos a crear un nuevo botón en nuestro formulario llamada Guardar Data y estará atado nuestra función guardarData, veamos como luce nuestro código con las modificaciones:

<html lang='en'>
<head> <title>Data Externa</title>
			    <meta charset='utf-8' />
</head>
<body>

<h1>Accediendo a data externa</h1>
<form action="#" method="post">
			    <p>Nombre completo: <input data-bind='value: nombre' /></p>
			    <p>Apellido: <input data-bind='value: apellido' /></p>

<div>
			    Actividades preferidas:
			    <select data-bind='options: actividades, value: hobbies'></select>
</div>
<p><button data-bind='click: cargarDataUsuario'>Cargar data</button></p>
<p><button data-bind='click: guardarData'>Guardar data</button></p>
</form>

<script src="js/knockout-3.3.0.js" type="text/javascript"></script>
<script src="//oss.maxcdn.com/jquery/1.11.1/jquery.min.js"></script>
<script type='text/javascript'>

function UsuarioViewModel() {
			    var self = this;
			    self.nombre = ko.observable("");
			    self.apellido = ko.observable("");
			    self.actividades = ko.observableArray([]);
			    self.hobbies = ko.observable("");


self.cargarDataUsuario = function() {
 $.getJSON("informacion_usuario.json", function(data) {

			    self.nombre(data.nombre);
			    self.apellido(data.apellido);
			    self.actividades(data.actividades);
			    self.hobbies(data.hobbies);

});
}

self.guardarData = function() {
			    alert(ko.toJSON(self));
}


}

 ko.applyBindings(new UsuarioViewModel());
</script>
</body>
</html>
Si ejecutamos nuestro ejemplo en el navegador vemos como tenemos un nuevo botón, cargamos nuestros valores, los cuales si deseamos podemos modificarlos. Por último presionamos el botón correspondiente el cual nos debería mostrar los valores en nuestro formulario como un string en formato JSON, veamos como luce:

 

 

Por último si deseamos que esta data sea enviado a algún script de nuestro servidor solo debemos realizar algunos cambios en nuestra función recién creada y al utilizar el método $.post completamos el proceso, para finalizar veamos como luce:

self.guardarData = function() {
 var data_enviar = {userData: ko.toJSON(self)};
 $.post("/guardar-data", data_enviar, function(data) {
			    alert("La informacion ha sido enviada al servidor");
 });
}

Mapeo de data a las VistaModelos


La manera en la que manejamos nuestra información proveniente de un JSON es todo lo que necesitamos para realizar aplicaciones robustas e implementar cualquier tipo de solución independiente del lenguaje del lado servidor, siempre y cuando se manejen con JSON.

 

Pero podemos ir un poco más allá y de manera automática mapear la data del JSON desde el servidor a nuestra VistaModelo y esto lo podemos lograr con un plug-in para Knockout.js llamado knockout-mapping. Para empezar a utilizarlo debemos primero descargarlo de su repositorio en GitHub, lo descomprimimos dentro de nuestro proyecto y lo incluimos luego de nuestro framework para evitar errores por la falta de dependencias.

 

Ahora solo debemos modificar nuestro código y eliminar nuestro botón de Cargar Data, así como toda la lógica de Knockout.js, ya que gracias a nuestro plug-in la obtención de la información será mucho más sencilla, veamos nuestro código final:

<html lang='en'>
<head> <title>Data Externa</title>
			    <meta charset='utf-8' />
</head>
<body>

<h1>Utilizando knockout-mapping</h1>
<form action="#" method="post">
			    <p>Nombre completo: <input data-bind='value: nombre' /></p>
			    <p>Apellido: <input data-bind='value: apellido' /></p>

<div>
			    Actividades preferidas:
			    <select data-bind='options: actividades, value: hobbies'></select>
</div>

</form>

<script src="js/knockout-3.3.0.js" type="text/javascript"></script>
<script src="js/knockout-mapping.js" type="text/javascript"></script>
<script src="//oss.maxcdn.com/jquery/1.11.1/jquery.min.js"></script>
<script type='text/javascript'>

$.getJSON("informacion_usuario.json", function(data) {
			    var UsuarioViewModel = ko.mapping.fromJS(data);
			    ko.applyBindings(UsuarioViewModel); });

</script>
</body>
</html>
Como vemos nuestra lógica quedo reducida a solo tres líneas de código, el cual lo que hace es al momento de que nuestra aplicación carga, inmediatamente realiza una petición Ajax del JSON el cual debe corresponder con los elementos de nuestro formulario. Este toma los objetos nativos de JavaScript y transforma cada propiedad en un observable, evitando todas esas líneas de código y haciendo no solo nuestra aplicación más robusta sino nuestro código más legible.

 

Para finalizar si ejecutamos nuestra aplicación vemos como automáticamente nuestros valores cargan en nuestro formulario y podemos ver la petición Ajax junto con el JSON de respuesta si usamos la consola del navegador:

 

data-externa2.jpg

 

Así finalizamos este tutorial, donde pudimos ver como Knockout.js nos ofrece una forma de enviar y almacenar data sin importar el lenguaje del lado del servidor que se esté utilizando, esto dándonos mayor libertad en nuestra implementación al solo cambiar el lenguaje del servidor por PHP, Ruby o Python por mencionar algunos.


¿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