Eventos y Modelos en Backbone.js

0
4215

Eventos y Modelos en Backbone.js

Índice de contenidos.


1. Introducción

En el anterior tutorial, ‘Introducción a Backbone.js’, hicimos una pequeña introducción sobre este potente framework javascript que nos permite desarrollar aplicaciones SPA (Single Page Application), permitiendo implementar de manera sencilla el patrón MVC (Model View Controller), en todas ellas.

Pues bien, en este tutorial, como ya os comenté, daremos un paso más y nos adentraremos en cómo usar los eventos y modelos de Backbone.js en nuestra aplicación.


2. Eventos

Como os comenté en ‘Introducción a Backbone.js’, la forma que tenemos para comunicar las distintas partes de nuestra aplicación es mediante el lanzamiento de eventos entre sí. Es decir, podemos hacer que una vista se suscriba a determinados eventos de un modelo para que cuando éste cambie y lance dichos eventos, la vista renderice ese cambio de alguna manera.

En Backbone, los eventos son un módulo más dentro de la librería. En nuestra aplicación, para dar a un objeto la habilidad de poder lanzar un evento que sea escuchado por el resto de componentes, tendremos que extender la funcionalidad de dicho objeto con la clase Backbone.Events:

	var testObject = {};
	_.extend(testObject, Backbone.Events);

Función ‘trigger’

A partir de este momento nuestro objeto podrá lanzar eventos en el contexto de nuestra aplicación que serán escuchados por todos los componentes que se encuentren suscritos al mismo. Para ello usaremos la función ‘trigger’. Esta función recibe por parámetro el nombre del evento y los argumentos que queramos enviar al callback que se ejecutará cuando se lance dicho evento:

	var params = 'estoy lanzando un evento'
	testObject.trigger('test:fire:event', params);

Por convención, y para diferenciar los eventos de una aplicación, en los nombres de los eventos usaremos los dos puntos (:), en el nombrado de los mismos (en el ejemplo anterior: ‘test:fire:event’)

Función ‘on’

Para que el resto de componentes de la aplicación, que necesiten escuchar el evento lanzado, puedan reaccionar al evento, será necesario que se suscriban a dicho evento. Para ello usaremos la función ‘on’. Esta función recibe por parámetro el nombre del evento que se escuchará y la callback que se ejecutará cuando el evento se lance:

	var listener = {};
	_.extend(listener, Backbone.Events);
	listener.on('test:fire:event', function(data) {
		console.log(data)
	});

Función ‘listenTo’

La particularidad que tiene la función anterior es que el evento es lanzado a toda la aplicación y todos los componentes de dicha aplicación serán capaces de escuchar dicho evento. Pero puede algún componente sólo quiera escuchar un evento determinado. Para este caso usaremos la función ‘listenTo’. Esta función permite escuchar eventos de un determinado objeto. Recibe por parámetro la instancia del objeto a escuchar, el nombre del evento y el callback a ejecutar cuando el evento se lance:

	var listener = {};
	_.extend(listener, Backbone.Events);
	listener.listenTo(testObject, 'test:fire:event', function(data) {
		console.log(data)
	});


3. Modelos

Dentro de una aplicación javascript, los modelos son la parte más importante de la misma. Contienen y manejan los datos de la aplicación y se encargarán de gestionar la lógica de nuestra aplicación.

Para crear un modelo, necesitamos extender de la clase Backbone.Model:

	var Alumno = Backbone.Model.extend({});

Constructor

Una vez creado nuestro modelo Alumno podemos crear instancias del modelo usando la palabra reservada ‘new’.

	var alumno = new Alumno({});

Del mismo modo podemos crear una instancia pasándole por parámetro un hash con atributos y valores de los mismos que se van a dar de alta en el modelo:

 
	var alumno = new Alumno({
		nombre: 'Ismael',
		apellidos: 'Fernandez Molina',
		dni: '77777777S',
		edad: 30,
		titulacion: 'Ingeniería Informática'
	});

defaults

Para crear un modelo con atributos por defecto usaremos el hash ‘defaults’, el cual creará de forma automática los atributos indicados con los valores indicados cada vez que creemos una instancia del modelo.

	var Alumno = Backbone.Model.extend({
		defaults: {
			nombre: '',
			apellidos: '',
			dni: '',
			edad: 0,
			titulacion: ''
		}
	});

	var alumno = new Alumno();

Función ‘get’

Para recuperar valores de los atributos de una instancia de un modelo, usaremos la función ‘get’. Para recuperar los valores pasaremos por parámetro una cadena con el nombre del atributo:

	var alumno = new Alumno({
	    nombre: 'Ismael',
	    apellidos: 'Fernandez Molina',
	    dni: '77777777S',
	    edad: 30,
	    titulacion: 'Ingeniería Informática'
	});
	 
	console.log(alumno.get('nombre'));
	console.log(alumno.get('apellidos'));
	console.log(alumno.get('edad'));
	console.log(alumno.get('titulacion'));
	console.log(alumno.get('dni'));

Función ‘set’

Para setear valores a un atributo del modelo usaremos la función ‘set’. Esta función recibe por parámetro el nombre del atributo y el valor que le vamos a dar:

	alumno.set('nombre', 'Manuel');
	alumno.set('apellidos', 'García Montes');
	alumno.set('edad', '22');

Si necesitamos cambiar varios valores a la vez, esta función también está preparada para recibir un hash con todos los valores que queramos cambiar:

	alumno.set({
		nombre: 'Manuel',
		apellidos: 'Garcia Montes',
		edad: 22
	});

Función ‘unset’

Para eliminar atributos de un modelo usaremos la función ‘unset’. Esta función recibe por parámetro el nombre del atributo a eliminar del modelo:

	var alumno = new Alumno({
	    nombre: 'Ismael',
	    apellidos: 'Fernandez Molina',
	    dni: '77777777S',
	    edad: 30,
	    titulacion: 'Ingeniería Informática'
	});
	 
	alumno.unset('titulacion');
	alumno.unset('edad');

Atributo ‘cid’

El atributo ‘cid’ es una cadena auto-generada por Backbone que identifica cada una de las instancias de los modelos que se van a creando en nuestra aplicación. No es aconsejable usar este atributo como identificador del modelo. Será necesario que creemos nuestro propio identificador para gestionar nuestras entidades para no tener problemas con el ‘cid’:

	var alumno = new Alumno({
		nombre: 'Ismael',
		apellidos: 'Fernandez Molina',
		dni: '77777777S',
		edad: 30,
		titulacion: 'Ingeniería Informática'
	}),
	alumno2 = new Alumno({
		nombre: 'Manuel',
		apellidos: 'Garcia Montes',
		dni: '77777777S',
		edad: 30,
		titulacion: 'Ingeniería Informática'
	});
	 
	console.log(alumno.cid);
	console.log(alumno2.cid);

Atributo ‘id’

Para definir el identificador del modelo setearemos el atributo ‘id’ el cual será usado como identificador único del modelo y usado para crear las URLs de persistencia con el servidor.

	var alumno = new Alumno({
	    nombre: 'Ismael',
	    apellidos: 'Fernandez Molina',
	    dni: '77777777S',
	    edad: 30,
	    titulacion: 'Ingeniería Informática'
	});
	 
	alumno.set('id', '984651');

Atributo ‘idAttribute’

Como acabamos de ver, Backbone usará el atributo ‘id’ como identificador del modelo si lo definimos. Si la comunicación con el backend es directa y el identificador del modelo en el backend no se llama ‘id’, podemos indicar a Backbone que use otro atributo como identificador. Para ello usaremos el atributo ‘idAttribute’:

var Alumno = Backbone.Model.extend({
    idAttribute: 'codAlumno',
    defaults: {
	   nombre: '',
	   apellidos: '',
	   dni: '',
	   edad: 0,
	   titulacion: ''
    }
});


4. Sincronización con el backend

Los modelos de Backbone vienen preparados para dar soporte a la persistencia de datos. Ofrece una serie de funciones que nos serán muy útiles a la hora almacenar los datos y, de la misma forma, nos ahorrará tiempo ya que no tendremos que desarrollar de forma manual las llamadas a los backend’s.

Backbone.sync

Backbone nos proporciona una función que nos permite interaccionar con los backends para persistir o recuperar datos de modelos. Dicha función es Backbone.sync. Esta función recibe por parámetro el método que se va a ejecutar («create», «read», «update», «delete»), el modelo en cuestión y parámetros opcionales como los callbacks cuando la función ha funcionado correctamente o ha fallado.

El funcionamiento de Backbone.sync es el siguiente: cuando lanzamos una llamada al backend con Backbone.sync, ésta coge todos los atributos del modelo, convierte los datos en un json y lanza una petición HTTP indicando que los datos que van a viajar son de tipo json (content-type: application/json). En función de la respuesta del backend (si devuelve datos o no), el modelo se actualizará con los datos que se devuelvan o no.

Como ya hemos indicado anteriormente, Backbone buscará el identificador del modelo para construir las llamadas (REST), a los backends. De esta forma tendremos lo siguiente:

metodo:’read’ –> verbo:GET –> url:’/modelName[/id]’

metodo:’create’ –> verbo:POST –> url:’/modelName’

metodo:’update’ –> verbo:PUT –> url:’/modelName/id’

metodo:’patch’ –> verbo:PATCH –> url:’/modelName/id’

metodo:’delete’ –> verbo:DELETE –> url:’/modelName/id’

Función ‘fetch’

Esta función llama internamente a Backbone.sync para recuperar los datos del modelo procedentes del backend.

	var alumno = new Alumno({
	  id: 1
	  nombre: '',
	  apellidos: '',
	  dni: '',
	  edad: 0,
	  titulacion: ''
	});

	alumno.fetch();

Función ‘save’

Esta función llama internamente a Backbone.sync para almacenar los datos del modelo en el backend (ya sea en el servidor, fichero, etc.). Puede recibir por parámetro un hash con los datos del modelo que se van a modificar. Aunque luego, internamente enviará el hash completo con los datos del modelo. Si el modelo es un modelo ya existente, internamente se lanzará una actualización (method: update –> PUT), de lo contrario, si es nuevo, se lanzará un alta (method: create –> POST).

	var alumno = new Alumno({
	  id: 1
	  nombre: 'Ismael',
	  apellidos: 'Fernandez Molina',
	  dni: '77777777S',
	  edad: 30,
	  titulacion: 'Ingeniería Informática'
	});

	alumno.save({
	  nombre: 'Manuel',
	  apellidos: 'Garcia Montes'
	});

Esta función, cada vez que es llamada, realiza una llamada al método ‘validate’ del modelo, si éste lo tiene definido, para comprobar si los datos del modelo son correctos y si se puede seguir con el guardado de datos. En el caso de que el método ‘validate’ indicase lo contrario, la función ‘save’ se abortaría y se devolvería un callback con el error. El método ‘validate’ recibe por parámetro un objeto con los atributos del modelo.

	var Alumno = Backbone.Model.extend({
	  defaults: {
	   nombre: '',
	   apellidos: '',
	   dni: '',
	   edad: 0,
	   titulacion: ''
	  },
	  validate: function(attributes) {
	    if (attributes.id <= 0) {
	      return 'El id del alumno no es válido';
	    }
	  }
	});

Función ‘destroy’

Esta función elimina un modelo del backend. Al igual que las anteriores, delega la responsabilidad a Backbone.sync, el cual lo traducirá a una petición HTTP de tipo DELETE.

var alumno = new Alumno({
  id: 1
  nombre: 'Ismael',
  apellidos: 'Fernandez Molina',
  dni: '77777777S',
  edad: 30,
  titulacion: 'Ingeniería Informática'
});

alumno.destroy();


5. Eventos lanzados por defecto

Al principio de este tutorial hemos hablado sobre cómo podemos hacer que determinadas partes de nuestra aplicación escuchen los eventos que los modelos pueden lanzar. Los ejemplos que he mostrado son para los casos en los que nosotros programemos de forma manual ese lanzamiento de evento. De los que no hemos hablado son de los eventos que los modelos de Backbone ya lanzan por defecto cada vez que algo ocurre con los datos que éstos manejan.

Aquí os dejo la lista de eventos que se lanzan por defecto:

add — cuando un modelo es añadido a una colección (en el siguiente tutorial hablaremos sobre las colecciones)

remove — cuando un modelo se elimina de una colección

change — cada vez que un atributo de un modelo se actualiza

change:[attribute] — cada vez que un atributo específico del modelo ([atribute]), se actualiza

destroy — cuando un modelo se ha eliminado

request — cuando un modelo inicia una petición hacia el backend

sync — cuando la llamada que un modelo hace hacia el backend se ha ejecutado de forma satisfactoria

error — cuando la llamada que un modelo hace hacia el backend ha fallado

invalid — cuando la validación de un modelo ha fallado

all — este evento se lanza cada vez que cualquier evento es lanzado en nuestra aplicación

Llegado a este punto os puedo decir que los modelos de Backbone contienen muchas más funciones relacionadas con el manejo de los datos. Aquí os he detallado algunas de las principales y que más vais a usar a la hora de desarrollar una aplicación. Si queréis ampliar vuestro conocimiento sobre las funciones que nos proporcionan los modelos de Backbone podéis echarle un ojo a la documentación oficial de Backbone.js


6. Conclusiones

Como podéis ver, Backbone nos proporciona una multitud de funciones para el manejo de modelos en nuestra aplicación. Como hemos comentado, los modelos serán el core de nuestra aplicación y mediante la multitud de funciones y utilidades que ya nos proporciona este potente framework seremos capaces de gestionar la lógica de la aplicación de manera sencilla. Es cuestión de práctica el controlar su funcionamiento.

Pero no solo reside aquí su potencia. Quizá el punto más interesante de este framework es la sencillez con la que somos capaces de comunicar nuestra aplicación con los backends gracias Backbone.sync.

Poco a poco iremos ampliando la funcionalidad de este framework para que finalmente podamos dejaros una pequeña aplicación aplicando todo lo aprendido.

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad