47

Primeros pasos con Backbone js, por Xavier Aznar

Embed Size (px)

Citation preview

Page 1: Primeros pasos con Backbone js, por Xavier Aznar
Page 2: Primeros pasos con Backbone js, por Xavier Aznar

Primeros pasos con Backbone.js

Introducción a Backbone.js por Xavi Aznar

Índice

1. Primeros pasos 4

1.1. Requisitos básicos . . . . . . . . . . . . . . . . . . . . . . . . 4

1.2. Enlazando Backbone . . . . . . . . . . . . . . . . . . . . . . 4

2. Modelos 5

2.1. Nuestro primer modelo . . . . . . . . . . . . . . . . . . . . . 5

3. Colecciones 9

4. Vistas 19

5. Plantillas 25

6. Controladores y Eventos 30

7. Eventos y vistas 31

8. Single Page Applications (aplicaciones de una sola página) 33

9. Routers 37

10.Comunicación con el servidor 40

2

Page 3: Primeros pasos con Backbone js, por Xavier Aznar

ÍNDICE ÍNDICE

Comentarios de la adaptación del tutorial al

formato offline

Este eBook es la versión offline del tutorial que se encuentra colgado

en http://bit.ly/1erosPasosBackbone. El tutorial fue pensado como un

bloc de notas donde recoger mis progresos con Backbone. Poco a poco

se fue convirtiendo en un manual con el que iniciarse con uno de los

frameworks más potentes del momento en Javascript.

El texto está creado para ser leído en el navegador, donde los fragmen-

tos de código pueden ejecutarse directamente en la consola de Javas-

cript.

Al realizar la adaptación a un formato offline, como el PDF, esta posi-

bilidad desaparece. Para evitar que el lector se quede sin el feedbackproporcionado por la consola de Javascript, cada fragmento de código

ejecutable en la web se acompaña de una captura de pantalla de la sa-

lida por consola. De esta manera, se consigue una experiencia similar

a la de leer el tutorial en la web. Cuando el código manipula el DOM

-por ejemplo, cuando se trata de vistas-, el texto incluye capturas de la

página web antes y después de la ejecución del código.

En cuanto a los enlaces que aparecen en la página web, en la versión

offline se han complementado con una nota al pie. El enlace sigue sien-

do válido -clickable- en un formato como el PDF, pero se incluye la url

como una nota a pie de página por si quieres imprimir el tutorial como

referencia.

Otro elemento que se queda fuera de la versión offline son los comen-

tarios. A través de los comentarios puedes expresar dudas, quejas,

agradecimientos, sugerencias, puntualizaciones, correcciones... Para

mí son extremadamente importantes, pues me dicen qué hago bien,

qué puedo mejorar... Me hacen saber que hay alguien ahí, al otro lado

a quienes sirve este tutorial... Por tanto, te animo a visitar la página

http://bit.ly/1erosPasosBackbone y hacer oir tu voz.

Esta adaptación la he realizado utilizando LYX (http://www.lyx.org/),

un programa libre y multiplataforma, que permite utilizar la potencia

y flexibilidad del TEX y LATEX a través de un entorno gráfico que facilita

su utilización.

3

Page 4: Primeros pasos con Backbone js, por Xavier Aznar

1 PRIMEROS PASOS

1. Primeros pasos

1.1. Requisitos básicos

En primer lugar, necesitas un navegador compatible con herramientas

de desarrollador para ver qué está pasando en la consola. Cualquier

navegador moderno servirá, aunque para elaborar este tutorial he uti-

lizado Google Chrome.

Para abrir la consola en Google Chrome, haz click en cualquier lugar

de la página web y elige Inspect Element del menú contextual. Selec-

ciona Console en la parte superior del panel con las herramientas de

desarrollo. También puedes pulsar Crtl + Shift + J (o a través del

menú de Chrome → Tools → Javascript console).

1.2. Enlazando Backbone

Para poder praticar con Backbone, es recomendable que crees una pá-

gina web en la que enlaces los diferentes componentes que requiere

Backbone: jQuery, Underscore, json2 y backbone:

<script type="text/javascript" src="jquery/jquery.min.js"></script>

<script type="text/javascript" src="backbone/json2.min.js"></script>

<script type="text/javascript"

src="backbone/underscore.min.js"></script>

<script type="text/javascript" src="backbone/backbone.min.js"></script>

Aunque Backbone.js sólo tiene como dependencia indispensable a underscore,

para realizar manipulación del DOM y poder gestionar persistencia

RESTful completa, necesitas también json2 y jQuery.

En realidad, json2 sólo es necesario si quieres dar soporte a navegado-

res antiguos que no tengan soporte nativo para JSON, lo que cada día

es menos frecuente.

Para seguir los ejercicios de este tutorial, mantén siempre

abierta la consola de Javascript de tu navegador.

4

Page 5: Primeros pasos con Backbone js, por Xavier Aznar

2 MODELOS

2. Modelos

2.1. Nuestro primer modelo

En primer lugar, creamos un modelo extendiendo la clase Model de

Backbone. De esta forma creamos nuestra clase personalizada de Mo-delo. No parece un gran avance, pero en realidad Backbone nos ha pro-

porcionado una serie de métodos para establecer (set) y obtener (get)

propiedades de nuestro modelo, entre muchas otros métodos útiles.

Utilizamos la convención habitual de que los nombres de las

clases empiezan por mayúscula y las instancias, por minús-

culas.

El siguiente código muestra en la consola la creación de un modelo:

Contacto = Backbone.Model.extend();

contacto = new Contacto();

console.log( contacto );

En la consola vemos que se ha creado algo... Utilizamos el método

.toJSON() para convertir el objeto a formato JSON.

5

Page 6: Primeros pasos con Backbone js, por Xavier Aznar

2.1 Nuestro primer modelo 2 MODELOS

Utilizamos los métodos heredados de Model para establecer y obtener

la propiedad nombre:

Contacto = Backbone.Model.extend(); contacto = new Contacto();

contacto.set( ’nombre’, ’Anthony Machine’ );

console.log( contacto.toJSON() ); console.log( ’El nombre del contacto

es ’ + contacto.get( ’nombre’ ) );

Durante la creación de nuestra instancia del modelo podemos pasar

pares de clave:valor en un solo paso:

Contacto = Backbone.Model.extend();

contacto = new Contacto({

’nombre’: ’Anthony Machine’,

’telefono’: ’555-123-456’

});

console.log( contacto.toJSON() );

console.log( ’El telefono de ’ + contacto.get( ’nombre’ ) + ’ es el ’

+ contacto.get( ’telefono’ ) );

También podemos especificar valores por defecto en la creación de

nuestro modelo personalizado. Los valores por defecto se asignan si no

se especifica un valor para la propiedad (como en el caso del telefono

del segundo contacto):

Contacto = Backbone.Model.extend({

defaults: {

’nombre’: ’John Doe’,

6

Page 7: Primeros pasos con Backbone js, por Xavier Aznar

2.1 Nuestro primer modelo 2 MODELOS

’telefono’: ’900-123-456’

}

});

contactoDesconocido = new Contacto();

contactoManoli = new Contacto({ ’nombre’: ’Manoli’ });

console.log( contactoDesconocido.toJSON() );

console.log( contactoManoli.toJSON() );

También podemos asignar funciones que actualicen una propiedad de

forma programable. En este caso, lanzamos la función desde la consola

para actualizar el nombre de un contacto creado con los valores por

defecto.

Contacto = Backbone.Model.extend({

defaults: {

’nombre’: ’John Doe’,

’telefono’: ’900-123-456’

},

actualizaNombre: function(){

var nuevoNombre = prompt( ’Introduce el nuevo nombre para el

contacto: ’ );

this.set( {’nombre’: nuevoNombre} );

}

});

contacto = new Contacto();

console.log( contacto.toJSON() );

contacto.actualizaNombre();

console.log( contacto.toJSON() );

En primer lugar, preguntamos al usuario el nombre que quiere asignar

al contacto y después mostramos en la consola cómo hemos actualiza-

do la propiedad nombre del contacto con el valor proporcionado.

7

Page 8: Primeros pasos con Backbone js, por Xavier Aznar

2.1 Nuestro primer modelo 2 MODELOS

Finalmente, vamos a añadir una función que vigile los cambios que

se producen en la instancia del modelo creado y que nos avise al pro-

ducirse un cambio. Este tipo de funciones se denominan listeners en

inglés.

El listener escucha cambios en el valor de nombre y lanza una función

que registra el cambio en la consola.

Contacto = Backbone.Model.extend({

defaults: {

’nombre’: ’John Doe’

},

actualizaNombre: function( nuevoNombre ){

this.set({ ’nombre’: nuevoNombre });

}

});

// Creación del contacto con el nombre por defectocontacto = new Contacto();

console.log( contacto.toJSON() );

// Listener

8

Page 9: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

contacto.on( ’change:nombre’, function(){

console.log( ’Nombre del contacto modificado!’ )

} );

// Actualizamos el nombrecontacto.actualizaNombre( ’Miguel Campoviejo’ );

console.log( contacto.toJSON() );

3. Colecciones

Las colecciones (Collection) son conjuntos ordenados de modelos.

Como en el caso de los modelos, para crear una colección extendemos

la clase Collection proporcionada por Backbone.

Como una colección no es más que un conjunto de modelos, al crear la

colección debemos especificar el tipo de modelo que contiene. También

tenemos que especificar una url. Esto es necesario porque al realizar al-

guna operación CRUD, Backbone intenta conectar mediante REST con

la capa de persistencia, es decir, un servidor al otro lador de la URL que

le proporcionamos; allí completará la acción de creación, actualización

o eliminación de los datos de la colección. Si no proporcionamos esta

URL, aparecerán errores en la consola de Javascript.

Creamos la colección y la instanciamos, mostrando el resultado en la

consola usando el método .toJSON():

Contacto = Backbone.Model.extend();

Contactos = Backbone.Collection.extend({

Model: Contacto,

9

Page 10: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

url: "#"

});

contactos = new Contactos();

console.log( contactos.toJSON() );

El resultado es un array vacío. Una colección es un array de objetos,

pero la colección no contiene todavía ningún elemento. Utilizamos el

método .add() para añadir modelos a la colección.

Contacto = Backbone.Model.extend();

Contactos = Backbone.Collection.extend({

Model: Contacto,

url: "#"

});

contactos = new Contactos();

contactos.add({ ’nombre’: ’Anthony Machine’ });

console.log( contactos.toJSON() );

10

Page 11: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

Podemos añadir tantos objetos como queramos, repitiendo la acción

.add():

Contacto = Backbone.Model.extend();

Contactos = Backbone.Collection.extend({

Model: Contacto,

url: "#"

});

contactos = new Contactos();

contactos.add({ ’nombre’: ’Anthony Machine’ });

contactos.add({ ’nombre’: ’Miguel Campoviejo’ });

console.log( contactos.toJSON() );

En vez de añadir los elementos de la colección uno a uno, podemos

añadirlos durante la creación de la instancia de la colección:

Contacto = Backbone.Model.extend();

Contactos = Backbone.Collection.extend({

model: Contacto,

url: "#"

});

contactos = new Contactos([

{ ’nombre’: ’Anthony Machine’ },

11

Page 12: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

{ ’nombre’: ’Miguel Campoviejo’ }

]);

console.log( contactos.toJSON() );

Podemos añadir un contacto a la colección en la posición que deseemos

utilizando at. El siguiente código añade contacto1 en la posición 1

usando at, mientras que el contacto2 se añade al final (posición por

defecto).

Del mismo modo, usamos remove para eliminar un elemento de la co-

lección:

Contacto = Backbone.Model.extend();

contacto1 = new Contacto({ ’nombre’ : ’Mary Sun’ });

contacto2 = new Contacto({ ’nombre’ : ’Federico Mercurio’ });

Contactos = Backbone.Collection.extend({

model: Contacto,

url: "#"

});

contactos = new Contactos([

{ ’nombre’: ’Anthony Machine’ },

{ ’nombre’: ’Miguel Campoviejo’ }

]);

contactos.add( contacto1, {at : 1} );

console.log( contactos.toJSON() );

12

Page 13: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

contactos.add( contacto2 );

console.log( contactos.toJSON() );

// Eliminamos el primer elemento :primerElemento = contactos.at(0);

contactos.remove( primerElemento );

console.log( contactos.toJSON() );

// Eliminamos un objeto determinadocontactos.remove( contacto2 );

console.log( contactos.toJSON() );

Vamos a verlo con un poco más de detalle;

1. Creamos la colección con dos contactos, y añadimos contacto1

en la posición 1. Después, añadimos contacto2 sin especificar la

posición, de manera que se añade al final de la colección:

13

Page 14: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

2. Eliminamos el contacto situado en la posición 0 de la colección:

14

Page 15: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

3. Finalmente, eliminamos el contacto2 (no hace falta especificar la

posición; Backbone lo busca y lo elimina esté donde esté):

15

Page 16: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

Si queremos actuar sobre todos los elementos de la colección, un mé-

todo como .each() nos resultará útil. En el siguiente ejemplo, recorre-

mos los elementos de la colección y mostramos el nombre en la consola:

Contacto = Backbone.Model.extend();

Contactos = Backbone.Collection.extend({

model : Contacto,

url : ’#’

});

contactos = new Contactos([

{ ’nombre’ : ’Anthony Machine’ },

{ ’nombre’ : ’Miguel Campoviejo’ },

{ ’nombre’ : ’Mary Sun’ }

]);

contactos.each( function( cadaContacto ){

console.log( ’El nombre del contacto es ’ + cadaContacto.get(

’nombre’ ) );

16

Page 17: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

} );

Finalmente, podemos establecer listeners que controlen si se producen

cambios en la colección. En el siguiente ejemplo, vigilamos el evento

add.

Contacto = Backbone.Model.extend();

Contactos = Backbone.Collection.extend({

model: Contacto,

url: ’#’

});

contactos = new Contactos();

//Listenercontactos.on( ’add’, function(){

console.log( "Has cambiado la colección!" );

} );

var nuevoContacto = new Contacto({

’nombre’ : ’Anthony Machine’

});

contactos.add( nuevoContacto );

17

Page 18: Primeros pasos con Backbone js, por Xavier Aznar

3 COLECCIONES

Un solo listener puede reaccionar a diferentes eventos; para ello sólo

tenemos que incluir los eventos separados por espacios. Modificamos

el código anterior para reaccionar tanto a la adición como a la elimi-nación de elementos de la colección.

Contacto = Backbone.Model.extend();

Contactos = Backbone.Collection.extend({

model: Contacto,

url: ’#’

});

contactos = new Contactos();

//Listenercontactos.on( ’add remove’, function(){

console.log( "Has cambiado la colección!" );

} );

var nuevoContacto = new Contacto({

’nombre’ : ’Anthony Machine’

});

console.log( ’(Contacto añadido)’ )

contactos.add( nuevoContacto );

console.log( ’(Contacto eliminado)’ );

contactos.remove( nuevoContacto );

18

Page 19: Primeros pasos con Backbone js, por Xavier Aznar

4 VISTAS

4. Vistas

El proceso para crear una vista (view en inglés) es extendiendo la clase

View proporcionada por Backbone. Creamos la clase sin ningún pa-

rámetro y examinamos qué es lo que nos proporciona una vista en

Backbone.

VistaPrincipal = Backbone.View.extend();

vistaPrincipal = new VistaPrincipal();

console.log( vistaPrincipal );

Al crear una vista obtenemos un objeto con diferentes propiedades. La

propiedad cid es el identificador interno asignado por Backbone a la

vista recién creada. Sin embargo, nos interesan más las propiedades

el y $el (abreviatura de elemento).

La propiedad el es el contenedor de la vista creada. Por defecto, Back-bone proporciona un div. Puedes pensar en una vista como una caja

en la que mostrar el interfaz de la aplicación web. Todo lo que ten-

gas que dibujar (render en inglés) en el interfaz -botones, formularios,

listas, etc- se mostrará dentro del elemento el de la vista.

Sin embargo, no debes pensar que la vista contiene el HTML de tu

aplicación; contienen la lógica necesaria para presentar al usuario los

datos contenidos en los modelos. La representación de los datos se

realiza, en general, usando algún sistema de plantillas como los mi-crotemplates de Underscore.js, Mustache, etc... Después de recoger los

19

Page 20: Primeros pasos con Backbone js, por Xavier Aznar

4 VISTAS

datos y combinarlos con la plantilla, la vista almacena el resultado en

el elemento el.

El siguiente ejemplo muestra como, por defecto, el elemento el de una

vista es un div vacío:

VistaPrincipal = Backbone.View.extend();

vistaPrincipal = new VistaPrincipal();

console.log( vistaPrincipal.el );

Por otro lado, $el es la referencia vía jQuery al objeto contenedor de la

vista (el div, en este caso). Así podemos hacer referencia al elemento y

utilizar los métodos proporcionados por jQuery para manipularlo. Por

ejemplo, $el.show(); sería equivalente a $(’div’).show(); (aunque

probablemente deberías ser más preciso con el selector).

Backbone proporciona un método render para dibujar la vista, aunque

por defecto no hace nada. Backbone permite utilizar cualquier sistema

para mostrar la interfaz en pantalla, así que debemos especificar cómo

se muestra: utilizando concatenación de cadenas, mediante un motor

de plantillas...

Empezamos utilizamos el método .append() de jQuery para añadir un

encabezado en la vista:

VistaPrincipal = Backbone.View.extend({

render: function(){

this.$el.append( ’<h1>Hola Backbone!</h1>’ );

return this;

}

});

20

Page 21: Primeros pasos con Backbone js, por Xavier Aznar

4 VISTAS

vistaApp = new VistaPrincipal();

vistaApp.render();

console.log( vistaApp.el );

Al llamar a la función render() de forma manual, hemos forzado a

dibujar el encabezado en el div de la vista. Sin embargo, como he-

mos utilizado .append(), si lanzamos .render() múltiples veces, el

contenido se añade también múltiples veces...

VistaPrincipal = Backbone.View.extend({

render: function(){

this.$el.append( ’<h1>Hola Backbone!</h1>’ );

return this;

}

});

vistaApp = new VistaPrincipal();

vistaApp.render();

vistaApp.render();

vistaApp.render();

console.log( vistaApp.el );

21

Page 22: Primeros pasos con Backbone js, por Xavier Aznar

4 VISTAS

Si esto no es lo que queremos, podemos utilizar .html() para estable-

cer el contenido de la vista, por ejemplo.

VistaPrincipal = Backbone.View.extend({

render: function(){

this.$el.html( ’<h1>Hola Backbone!</h1>’ );

return this;

}

});

vistaApp = new VistaPrincipal();

vistaApp.render();

vistaApp.render();

vistaApp.render();

console.log( vistaApp.el );

Si queremos que la vista se dibuje automáticamente, podemos utilizar

el método initialize. initialize se ejecuta al crear la instancia de

la vista.

VistaPrincipal = Backbone.View.extend({

22

Page 23: Primeros pasos con Backbone js, por Xavier Aznar

4 VISTAS

initialize: function(){

this.render();

},

render: function(){

this.$el.html( ’<h1>Hola Backbone!</h1>’ );

return this;

}

});

vistaApp = new VistaPrincipal();

console.log( vistaApp.el );

Hasta ahora, toda la acción ha tenido lugar en la consola de Javascript.

El siguiente paso será conseguir mostrar la aplicación web en el nave-

gador. Backbone asigna por defecto al elemento el un div si no se ha

especificado tagName, className o id.

En el siguiente código asignamos una etiqueta H1 mediante tagName al

elemento el. Durante la inicialización de la vista, podemos establecer

variables, etc. En nuestro caso, preguntamos al usuario por su nom-

bre. Después, llamamos a la función render, que se encarga de dibu-

jar la vista. Finalmente, utilizamos jQuery para añadir la vista al DOM,

dentro de un div con id=vista01. Este elemento div id="vista01"

podría ser cualquier elemento previo del DOM, como body, por ejemplo.

Una vez la vista se añade al DOM, aparece en pantalla.

VistaPrincipal = Backbone.View.extend({

tagName : ’h1’,

initialize: function(){

var nombre = prompt ( ’Como te llamas? \n (Por defecto =

Backbone)’ );

23

Page 24: Primeros pasos con Backbone js, por Xavier Aznar

4 VISTAS

nombre = nombre || ’Backbone’;

this.render( nombre );

},

render: function( nombre ){

this.$el.text( ’Hola ’ + nombre +’!’ );

$( ’#vista01’ ).html( this.el );

return this;

}

});

vistaApp = new VistaPrincipal();

Entre el fragmento de código y el siguiente párrafo tenemos div id="vista01"

(vacío):

Cuando ejecutamos el código, se pregunta al usuario:

Se genera la vista y se añade al DOM, justo después del fragmento de

código:

24

Page 25: Primeros pasos con Backbone js, por Xavier Aznar

5 PLANTILLAS

En Backbone, las vistas incorporan también la funcionalidad asociada

a los elementos de la interfaz gráfica de la aplicación web. Es decir, que

además de la "V " (de Vista), del modelo MVC, también contienen los

controladores (la "C", del modelo MVC).

Al pulsar un botón, añadir un elemento o modificar algún dato en la

aplicación, establecemos listeners para los eventos que se disparen, y

así hacer que la aplicación actualice aquello que sea necesario.

5. Plantillas

Antes de entrar en el tema de la funcionalidad encapsulada en las vis-

tas, creo que es conveniente comentar cómo mostrar en las vistas los

datos contenidos en los modelos.

Backbone nos permite mostrar los datos contenidos en los modelos co-

mo queramos; no nos obliga a hacerlo de una forma determinada. El

método más básico y directo, es simplemente obteniendo los datos des-

de el modelo mediante un modelo.get( ’nombre’ ) e insertándolo en

el DOM.

Aunque podemos concaternar los valores obtenidos de los modelos con

etiquetas HTML y añadirlas directamente al DOM del documento, esta

solución no es la más recomendable.

Underscore.js proporciona un sistema de microplantillas que podemos

utilizar por defecto en nuestras aplicaciones, ya que underscore.js es

una dependencia de Backbone.js.

La función template permite insertar la información contenida en un

modelo, convirtiéndola a formato JSON, en un documento HTML. Para

ello, especificamos el nombre de la "clave" entre <%= ...%>, como se

muestra en el siguiente ejemplo:

25

Page 26: Primeros pasos con Backbone js, por Xavier Aznar

5 PLANTILLAS

plantilla = _.template( ’Hola <%= nombre %>. Me encanta tu tema <%=

cancion %>!’ );

console.log(

plantilla( {nombre: ’Anthony Machine’, cancion: ’Little black

angels’} )

);

_.template(...) analiza el código que le pasamos en busca de las

etiquetas <%= ...%> que indican dónde debe insertar los valores del

modelo. Si coinciden el nombre de la etiqueta y la clave del modelo,

inserta el valor correspondiente. Si no lo encuentra, se muestra un

error en la consola. Finalmente, devuelve el código de la plantilla con

los valores del modelo ya insertados.

Sin embargo, colocar trozos de código HTML junto con las etiquetas

del motor de plantillas proporcionado por Underscore.js en el código

javascript de la aplicación enturbia el código, haciéndolo menos legible

y claro.

La solución pasa por utilizar la otra dependencia de Backbone, jQueryy su capacidad para seleccionar y extraer elementos del DOM del do-

cumento HTML.

En el siguiente ejemplo selecciono el contenido del menú de navegación

con el contenido de este documento y lo muestro a través de la consola:

var $menu = $(’#menu ul’).html()

console.log( $menu );

26

Page 27: Primeros pasos con Backbone js, por Xavier Aznar

5 PLANTILLAS

Como ves, sólo necesitas saber qué quieres seleccionar. Puedes utilizar

el id, el nombre de la class o la etiqueta (entre otras muchas opcio-

nes).

La idea será colocar el HTML de la plantilla que quieres utilizar para

tus datos de la aplicación en el propio documento HTML. Para evitar

que aparezca en el navegador, lo encerramos entre etiquetas script.

Aunque el navegador no lo muestre, intentará interpretarlo como si

fuera javascript (por defecto). Pero tampoco es éso lo que queremos, así

que especificamos type="text/template; el navegador no sabrá como

interpretarlo y por tanto, lo ignorará. En realidad podemos clasificarlo

como text/LoQueSea, pero por convención se utiliza el tipo template

(plantilla, en inglés).

Finalmente, para poder acceder al fragmento de código que contiene la

plantilla con facilidad, lo designamos con un id único.

El fragmento de código a continuación muestra cómo podría ser una

plantilla para mostrar la información del siguiente ejemplo:

<script type="text/template" id="plantilla-vistapersonaje">

<h1> <%= nombre %> </h1>

<p>

<a href="<%= wikipediaurl %>" class="mas-info">

Información en la wikipedia sobre <%= nombre %>

</a>

</p>

</script>

27

Page 28: Primeros pasos con Backbone js, por Xavier Aznar

5 PLANTILLAS

Ahora, el código de la vista para el contacto será:

Personaje = Backbone.Model.extend();

VistaPersonaje = Backbone.View.extend({

el: ’#vista02’,

plantilla: _.template( $(’#plantilla-vistapersonaje’).html() ),

initialize: function( modelo ){

this.$el.html( this.plantilla ( modelo.toJSON() ));

},

render: function(){

$(’#vista02’).html( this.$el );

return this;

}

});

personaje = new Personaje({

’nombre’: ’Antonio Machín’,

’url’: ’http://es . wikipedia . org/wiki/Antonio_Mach %C3%ADn’})

vistaPersonaje = new VistaPersonaje( personaje );

Antes de ejecutar el código:

Y después, cuando hemos generado la vista a partir de la información

contenida en el modelo:

De esta forma conseguimos separar el código HTML de la plantilla de

la funcionalidad relacionada con la vista. No hace falta preocuparse

28

Page 29: Primeros pasos con Backbone js, por Xavier Aznar

5 PLANTILLAS

sobre cómo se van a mostrar los datos de la aplicación, de los estilos

o etiquetas en los que se encuentran. Sólo tienes que saber que en la

plantilla habrá un hueco con la clave del dato que se insertará en esa

posición (y dejar el diseño a un especialista, por ejemplo).

Si se modifica la plantilla...

<script type="text/template" id="plantilla-vistapersonaje2">

<ul>

<li> <a href="<%= url %>"> <%= nombre %> </a></li>

<li> <a href="<%= url %>"> <%= nombre %> </a></li>

<li> <a href="<%= url %>"> <%= nombre %> </a></li>

<li> <a href="<%= url %>"> <%= nombre %> </a></li>

</ul>

</script>

...el código no cambia:

Personaje = Backbone.Model.extend();

VistaPersonaje = Backbone.View.extend({

el: ’#vista02’,

plantilla: _.template( $(’#plantilla-vistapersonaje2’).html() ),

initialize: function( modelo ){

this.$el.html( this.plantilla ( modelo.toJSON() ));

},

render: function(){

$(’#vista02’).html( this.$el );

return this;

}

});

personaje = new Personaje({

’nombre’: ’Antonio Machín’,

’url’: ’http://es . wikipedia . org/wiki/Antonio_Mach %C3%ADn’})

vistaPersonaje = new VistaPersonaje( personaje );

sin embargo, la salida sí que es diferente, pues la plantilla que hemos

utilizado es diferente:

29

Page 30: Primeros pasos con Backbone js, por Xavier Aznar

6 CONTROLADORES Y EVENTOS

Hasta ahora, sabemos que la vista tiene una propiedad el, que contie-

ne una referencia a un elemento del DOM del documento. Mediante la

función _.template(...) de Underscore.js, extraemos el HTML de la

plantilla y lo combinamos con los datos almacenados en el modelo. Y

mediante render(...) lo dibujamos en el documento HTML.

Sin embargo, antes de empezar este apartado sobre plantillas decía que

las vistas también contienen funcionalidad asociada a los elementos

visuales de la aplicación. Vamos con esta funcionalidad...

6. Controladores y Eventos

En el modelo MVC una aplicación se encuentra separada en tres tipos

de componentes. En Backbone.js los controladores se incluyen en las

vistas, con lo que no podríamos hablar estrictamente de un modelo

MVC .

En realidad, en las primeras versiones de Backbone.js sí que

había una clase controller, solo que en la versión 0.5.0 se

renombró a router. Más adelante hablo de los routers.

El controlador no es más que una función que se encarga de reaccionar

a las acciones que realiza el usuario sobre los componentes visuales de

la aplicación y actualiza los datos del modelo en consecuencia.

Para poder reaccionar a las acciones del usuario necesitamos un siste-

ma que gestione los eventos que éste produce (hacer click en un botón,

enviar un formulario, etc).

30

Page 31: Primeros pasos con Backbone js, por Xavier Aznar

7 EVENTOS Y VISTAS

Backbone.js proporciona un sistema de gestión de eventos que permite

asociar listeners a los selectores incluidos en el elemento el (o directa-

mente a el si no se proporciona ningún selector). Los eventos se recogen

en forma de hash de la forma "evento selector" : "callback".

El siguiente ejemplo muestra lo que podría ser un hash de eventos para

una aplicación de agenda de contactos:

events : {

’dblclick label’ : ’muestraEditaContacto’,

’blur .editar’ : ’cierraEditaContacto’,

’click .elimina’ : ’eliminaContacto’

}

muestraEditaContacto, cierraEditaContacto y eliminaContacto

son funciones que deben estar definidas en el mismo ámbito de la vista.

En realidad, Backbone proporciona un sistema de eventos muy po-

tente, que va más allá de las vistas y que permite gestionar eventos

de modelos, colecciones, routers, el historial y de los objetos y eventos

propios que definas para tu aplicación.

Antes de centrarme en el uso de eventos relacionados con las vistas,

comentaré brevemente los Eventos en Backbone.js.

Backbone.Events puede utilizarse para asociar eventos personaliza-

dos a cualquier objeto que definamos.

7. Eventos y vistas

Una de las ventajas de Backbone.js es que los diferentes componentes

que integran la aplicación -modelos, vistas y el DOM- se comunican

31

Page 32: Primeros pasos con Backbone js, por Xavier Aznar

7 EVENTOS Y VISTAS

entre sí. Esta comunicación es bidireccional, tanto si se actualiza la

información contenida en el modelo como si se genera un evento en la

vista que afecta al modelo.

En Backbone.js la Vista hace de concentrador de todo lo que sucede

en nuestra aplicación. Ya hemos visto antes que un cambio en el mo-

delo permitía, a través de un listener, reaccionar ante un cambio en

el modelo. En general, cuando cambia la información contenida en los

modelos de nuestra aplicación querremos actualizar la vista, mostran-

do la información actualizada.

Del mismo modo, cuando se produce un evento en la vista, actualiza-

mos el modelo o la colección correspondiente.

32

Page 33: Primeros pasos con Backbone js, por Xavier Aznar

8 SINGLE PAGE APPLICATIONS (APLICACIONES DE UNA SOLAPÁGINA)

8. Single Page Applications (aplicaciones de

una sola página)

Hasta ahora hemos estado practicando directamente en la línea de co-

mando, creando modelos, colecciones y vistas. También hemos visto

que una de las ventajas de Backbone es que todos los elementos se

comunican entre sí, a través de eventos asociados a los diferentes mo-

delos o vistas de nuestra aplicación web. De hecho, Backbone.js pro-

porciona toda la infraestructura necesaria para crear lo que se denomi-

nan single page applications, es decir, una aplicación web de una sola

página. Esta página contiene el HTML, las CSS y el código javascript

necesario para interaccionar con los datos obtenidos desde el servidor

y mostrarlos a través de las vistas.

Imagina una aplicación de agenda como la que he dibujado más abajo.

En la vista principal se muestra la lista completa de contactos (sin

filtrar). Junto a cada uno de los contactos, tenemos un botón para

editar la información del contacto. Al pulsarlo, se muestra una nueva

página con la información del contacto.

33

Page 34: Primeros pasos con Backbone js, por Xavier Aznar

8 SINGLE PAGE APPLICATIONS (APLICACIONES DE UNA SOLAPÁGINA)

En una aplicación tradicional, el cliente solicita la página web al ser-

vidor, donde se procesa la petición. Inicialmente, se devuelve una lista

de todos los contactos. Cuando el cliente pulsa sobre un contacto para

editar los datos relacionados, se realiza la petición al servidor, que ob-

tiene los datos relativos al contacto seleccionado, se combinan con la

plantilla adecuada y se devuelven al cliente. Como todo el procesamien-

to de los datos se realiza en el servidor, cada vez que hay que tratar con

los datos, hay que contactar de nuevo con el servidor.

34

Page 35: Primeros pasos con Backbone js, por Xavier Aznar

8 SINGLE PAGE APPLICATIONS (APLICACIONES DE UNA SOLAPÁGINA)

En una aplicación con Backbone.js, los datos se procesan en el cliente

(el navegador): al solicitar la página, el servidor devuelve el documen-

to HTML que contiene todas las plantillas que necesitan las vistas de

la aplicación junto con los datos. Cuando el cliente interacciona con

la aplicación, no es necesario volver a contactar con el servidor, sino

simplemente cambiar la vista, filtrando los datos adecuados:

35

Page 36: Primeros pasos con Backbone js, por Xavier Aznar

8 SINGLE PAGE APPLICATIONS (APLICACIONES DE UNA SOLAPÁGINA)

El problema es que todas las vistas de la aplicación comparten la URL,

por lo que hay que proporcionar algún método para que el usuario

pueda acceder a una determinada funcionalidad de la aplicación web

(por ejemplo, a la visualización de un contacto determinado). Usando

REST esta URL será de la forma http://agenda.me/contacto/1, por

ejemplo. El problema es que esta URL no existe. Sin embargo, podemos

crear un enlace similar mediante el uso de una hash url; utilizando el

signo de la almohadilla # indicamos al navegador que el enlace apunta

a un fragmento de la página web, por lo que conseguimos URLs váli-

das como http://agenda.me/#contacto/1. Otro problema relaciona-

do con estas aplicaciones de una sóla página es que todos los enlaces

con hash urls no eran indexados por los buscadores. Pero desde hace

un tiempo los buscadores aceptan una especificación que permite inde-

xar todas estas URLs virtuales, por llamarlas de algún modo. Si quieres

que los buscadores indexen los enlaces de tu aplicación web, utiliza la

combinación #!. Puedes completar información al respecto échandole

un vistazo a https://developers.google.com/webmasters/ajax-crawling/

.

36

Page 37: Primeros pasos con Backbone js, por Xavier Aznar

9 ROUTERS

9. Routers

Para solucionar el problema de las URLs relacionados con la singlepage applications Backbone.js proporciona los router.

Hasta la llegada de la API History había que utilizar las hash urls (p.ej.

agenda.me/#edit) para proporcionar al usuario enlaces que pudieran

ser enlazables, bookmarkables, etc.

El problema es que para que un navegador pase de la URL agenda.me/contacto/1

a agenda.me/contacto/2, se requiere que se haga una petición al ser-

vidor y que este devuelva el contenido de la URL agenda.me/contacto/2.

Este proceso, llamado navegación actualiza la historia del navegador.

Así podemos pulsar los botones atrás/adelante del navegador para

avanzar/retroceder por el historial de navegación.

Con las urls fragmentadas, cuando el navegador pasa de agenda.me/#contacto/1

a agenda.me/#contacto/2 no se produce un cambio de página, sino

un cambio en la parte que se visualiza de una misma página. No hay

llamada al servidor y por tanto, no hay actualización de la historia de

navegación.

Con la llegada de este API, las aplicaciones web pueden manipular la

historia del navegador, de manera que un cambio de una URL a otra

-aunque sea una hash url- sí se interpreta como una navegación entre

páginas y, por tanto, queda registrado en la historia del navegador. De

esta forma las urls fragmentadas pasan a comportarse como urls deverdad y pueden utilizarse para enlazar, para añadir a favoritos, para

compartir por mail, etc.

Backbone.js proporciona la clase Backbone.router para gestionar es-

tos cambios de URLs en las aplicaciones del lado del cliente y asociarlas

a acciones y eventos. Además, para los navegadores que no soportan el

API de la historia de navegación el router se degrada de forma trans-

parente a la versión hash de la URL.

La creación de un router se realiza mediante la extensión de Backbone.Router,

como es habitual en Backbone.js.

Dentro de nuestra instancia de router definimos el conjunto de urlsinternas -llamadas rutas- de la aplicación y las funciones a las que

37

Page 38: Primeros pasos con Backbone js, por Xavier Aznar

9 ROUTERS

deben llamar cuando se navegue a una url determinada. En estas URLs

podemos incluir una o varias partes variables, que será interpretadas

como parámetros:

var Agenda = Backbone.Router.extend({

routes : {

"ayuda" : "ayuda",

"busca/:consulta" : "busca"

},

ayuda: function(){

...

},

busca: function( consulta ){

...

}

});

En el ejemplo anterior he definido dos rutas; la primera corresponde a

miagenda.#ayuda corresponde a una ruta básica. La aplicación mapea

la ruta agenda.me/#ayuda con la función ayuda.

En el segundo caso hemos definido la ruta añadiendo :consulta; de

esta manera indicamos que este fragmento de la URL es un paráme-

tro y que debe ser asignado a la variable consulta, que pasamos a la

función correspondiente. Es decir, agenda.me/#busca/antonio resul-

ta en busca( "antonio" ); en la aplicación.

Con estos dos tipos de rutas tienes las opciones más comunes para de-

finir rutas. De todas formas, consulta la documentación en Backbone.js/#Router

para descubrir otras formas de pasar parámetros desde las URLs a las

funciones de tu aplicación.

Una vez creadas y configuradas las rutas de la aplicación web, indica-

mos a Backbone.js que monitorice los eventos de cambio de hash urlsy ¡listo!

Backbone.history.start();

38

Page 39: Primeros pasos con Backbone js, por Xavier Aznar

9 ROUTERS

Podemos pasar opciones a start, por ejemplo, si queremos usar pushState

o si la página web no es servida directamente desde la raíz del do-

minio... Como siempre, es recomendable que mires la documentación

oficial completar información sobre History.

Una vez arrancada la monitorización de cambios en la url, Backbone.jsse encarga de actualizar el historial del navegador de forma automática.

Si desde la aplicación web queremos forzar la navegación de un punto

a otro de la aplicación, utilizamos el método navigate de router:

...

this.navigate( "pagina/" + numPagina );

...

Si la url a la que estamos navegando forma parte de las rutas definidas,

es probable que queramos que se dispare la función asociada definida

en la ruta; para ello, pasamos {trigger:true} a navigate:

routes: {

"ayuda/faq" : "faqMsg"

},

faqMsg: function(){

alert( ’Gracias por consultar las preguntas frecuentes’ );

}

...

agenda.navigate( "ayuda/faq", {trigger: true} );

En resumen, definimos unas rutas en Backbone.Router, que mapea-

mos a funciones relacionadas con las acciones que lleva a cabo la apli-

cación. Con Backbone.history.start() la aplicación reacciona au-

tomáticamente a los cambios de url, actualizando el historial de nave-

gación. Si desde la aplicación queremos simular una de estas navega-

ciones, usamos el método navigate.

39

Page 40: Primeros pasos con Backbone js, por Xavier Aznar

10 COMUNICACIÓN CON EL SERVIDOR

10. Comunicación con el servidor

Una de las ventajas de Backbone es que reduce las peticiones necesa-

rias al servidor. En su lugar, Backbone utiliza las vistas para mostrar

únicamente la información necesaria en la vista actual.

Los datos de una aplicación web se almacenan en lo que se llama la ca-pa de persistencia, que normalmente es una base de datos. Esta base

de datos se encuentra en el servidor, por lo que antes o después, desde

la aplicación web hay que establecer comunicación con el servidor para

actualizar datos. Backbone proporciona toda la infraestructura nece-

saria para realizar la comunicación entre el navegador y el servidor de

forma sencilla.

Primero comentaré lo que pasa en general, usando únicamente REST.

Después, veremos cómo Backbone ejecuta estos comandos a través del

módulo Backbone.sync. sync es un mecanismo de bajo nivel, dentro

del framework; en el día a día del desarrollo de la aplicación web uti-

lizaremos otros métodos propios de modelos, colecciones y vistas, que

son los que internamente utilizan sync y que comentaré al final de esta

sección.

Siguiendo con el ejemplo de la agenda, durante la primera conexión

Backbone descarga la información de todos los contactos. Después, si

el usuario consulta el contacto 1, muestra una vista de detalle con los

datos filtrados para ése único usuario, sin necesidad de ponerse en

contacto con el servidor de nuevo. A continuación vamos a entrar en

detalle sobre cómo se comunica Backbone para obtener y actualizar la

información.

En la documentación oficial de Backbone dice que proporciona un in-

terfaz REST completo a través de JSON (traducción libre de : [...] andconnects it all to your existing API over a RESTful JSON interface). ¿Qué

quiere decir ésto?. En la página en castellano de la Wikipedia encon-

tramos la definición del significado de REST, de donde destaca:

protocolo cliente/servidor sin estado: cada mensaje intercambia-

do contiene toda la información necesaria para comprender la pe-

tición.

40

Page 41: Primeros pasos con Backbone js, por Xavier Aznar

10 COMUNICACIÓN CON EL SERVIDOR

un conjunto de operaciones bien definidas: aunque incluye otras,

en la práctica se utilizan sólo cuatro GET, POST, PUT, DELETE.

sintaxis universal que permite identificar los recursos a través de

su URI.

Con estas ideas en mente, ahora volvemos a la aplicación de la agenda.

Cuando el usuario accede a http://agenda.me/, es decir a la raíz

de nuestra aplicación /, seguramente nos interese definir una route

hacia /contactos/. Como no especificamos ningún id de contacto,

si lo hemos programado así, nuestro servidor nos devolverá todos los

contactos almacenados en la base de datos (mediante GET).

Cuando el usuario introduce un nuevo contacto, enviamos la informa-

ción al servidor mediante POST; el servidor se encarga de asignar el

siguiente id libre en el equivalente en nuestra base de datos de la lista

de /contactos.

Si el usuario quiere acceder a un contacto concreto, como el que tiene el

id=5, en este caso el identificador (URI del recurso) será: /contactos/5,

de nuevo, usando GET.

Mediante DELETE indicamos que vamos a borrar un contacto. Para ello

debemos aportar el id del contacto a borrar; por ejemplo, como antes

/contactos/5.

Finalmente, usamos PUT para actualizar la información de un contacto

(o crear uno nuevo). Como es lógico, aportamos el id del contacto que

queremos acutalizar junto con la información actualizada.

Backbone proporciona toda esta funcionalidad a través de Backbone.sync.

sync toma tres parámetros: method, model y options (este último es

opcional). El method es uno de los cuatro verbos de REST: GET, POST,

PUT, DELETE. El segundo, model es el modelo a guardar en el servidor

(o la colección que vamos a leer); Backbone interpreta qué tiene que

hacer con los datos que le pasamos.

Enlazando con el ejemplo anterior de la agenda, por defecto sync sería

algo así:

crear nuevo contacto : POST →/contactos

41

Page 42: Primeros pasos con Backbone js, por Xavier Aznar

10 COMUNICACIÓN CON EL SERVIDOR

leer (contacto o colección): GET → /contactos[/id] Si no se pro-

porciona un id, es que queremos leer toda la colección.

actualiza un contacto : PUT → /contactos/id

borrar contacto : DELETE → /contactos/id

Aunque Backbone.sync usa jQuery.ajax(), en realidad podemos sus-

tituirlo por cualquier otro método que nos interese, en función de nues-

tras necesidades. Un ejemplo de ello es la aplicación localtodos, que

usa Backbone.localStorage. localStorage funciona como un plu-gin que usa el local storage (almacenamiento local) de HTML5 en vez de

un servidor de bases de datos como capa de almacenamiento.

Como he comentado al principio de esta sección, sync es un meca-

nismo interno de Backbone; al desarrollar la aplicación web rara vez

tendremos que llamar a sync de manera manual.

De nuevo volvemos al ejemplo de la agenda. La primera vez que el

usuario accede a la aplicación web crearemos una colección Contactos

donde almacenar localmente la información obtenida del servidor. En

la definición de la colección habremos incluido la propiedad url, que

indica a Backbone dónde buscar y almacenar los datos contenidos en

la colección. En la sección sobre Colecciones de este tutorial verás que

utilicé url: ’#’ para evitar que Backbone se intentara comunicar con

una url externa a la página.

Ahora, suponiendo que ya tenemos el servidor configurado, nuestra

colección incluiría:

Contactos = Backbone.Collection.extend({

Model: Contacto,

url: "/contactos/"

});

Así la colección sabe dónde están almacenados los datos con los que

se relaciona. Por tanto, en la función de inicialización de la colección

podemos incluir:

42

Page 43: Primeros pasos con Backbone js, por Xavier Aznar

10 COMUNICACIÓN CON EL SERVIDOR

initialize: function(){

...

Contactos.fetch();

...

};

fetch obtiene los datos almacenados en la url de la colección en el

servidor. En nuestro ejemplo de la agenda, obtendría todos los datos

almacenados en la base de datos, pasándolos a una vista y mostrándo-

los al usuario al visitar la página por primera vez. Incluso si llamamos

a fetch en respuesta a algún evento que se produce en la aplicación,

Backbone utiliza set para fusionar los datos locales con los obteni-

dos del servidor de forma inteligente (a no ser que utilicemos {reset:

true}). En las opciones de fetch podemos espeficificar funciones de

callback para los eventos success y error de comunicación con el ser-

vidor, actuando en consecuencia. A estas funciones Backbone les pasa

automáticamente collection, response y options como argumen-

tos. De hecho, fetch delega su ejecución a Backbone.sync de forma

transparente (que a su vez utiliza jQuery.ajax() para realizar la co-

municación con el servidor).

fetch hace que se disparen los eventos add para cada modelo añadido

y change para cada modelo cambiado. Así, si hemos especificado que

ocurran cosas cuando cambien los modelos -por ejemplo, actualizar

una vista- se ejecutará el código adecuado y todo funcionará sin que

tengamos que preocuparnos por ello.

fetch puede llamarse tanto para modelos como para colecciones. Si

url no está definido para el modelo, utiliza url de la colección asocia-

da. El único requerimiento para fetch es que el servidor devuelva un

array de modelos en formato JSON.

Volviendo la vista atrás un momento, tenemos que, lo que anteriormen-

te habíamos comentado:

leer (contacto o colección): GET → /contactos[/id] Si no se pro-

porciona un id, es que queremos leer toda la colección.

sería, mediante fetch:

43

Page 44: Primeros pasos con Backbone js, por Xavier Aznar

10 COMUNICACIÓN CON EL SERVIDOR

leer (contacto o colección):

Contactos.fetch()

(toda la colección) o

Contacto.fetch()

(para obtener un contacto en concreto).

Al obtener el contacto no tenemos que especificar el id del modelo, ya

que internamente Backbone sabe cuál es el id asociado a cada modelo

de una colección, y no hace falta que lo especifiquemos nosotros.

Para el resto de operaciones de creación, actualización o eliminación

de modelos, tal y como hemos hecho con fetch utilizamos funciones

específicas en vez de utilizar Backbone.sync a pelo.

Backbone proporciona el método save para guardar un nuevo modelo

en la base de datos o para actualizar uno existente.

Contacto = Backbone.Model.extend();

var contacto = new Contacto({

nombre: ’Anthony Machine’,

telefono: ’+34931234567’

});

contacto.save(); // Lo guarda en el servidor

El siguiente trozo de código (adaptado de la página de Backbone) mues-

tra una función sync modificada, que muestra un alert() en vez de

comunicarse con el servidor. Al ejecutar el código por primera vez, save

envía el modelo completo, ya que no existe inicialmente. En la segun-

da llamada a save, especificamos sólo la parte de la información del

contacto actualizada; Backbone te facilita el trabajo y no es necesario

utilizar funciones diferentes para crear y actualizar ni es necesario es-

cribir código para comprobar si un registro existe antes de modificarlo

y cosas por el estilo...

44

Page 45: Primeros pasos con Backbone js, por Xavier Aznar

10 COMUNICACIÓN CON EL SERVIDOR

Backbone.sync = function(method, model) {

alert(method + ": " + JSON.stringify(model));

model.id = 1;

};

var contacto = new Backbone.Model({

nombre: "Anthony Machine",

telefono: "+34931234567"

});

// Primera llamada : crea e l contactocontacto.save();

// Segunda llamada : actualiza e l contacto ( que ya existe )contacto.save({nombre: "Federico Mercurio"});

En la primera llamada:

Y en la segunda:

45

Page 46: Primeros pasos con Backbone js, por Xavier Aznar

10 COMUNICACIÓN CON EL SERVIDOR

Para evitar enviar el modelo completo, podemos utilizar el parámetro

{patch: true} que envía sólo los atributos modificados al servidor,

optimizando las comunicaciones. Backbone utiliza isNew() para de-

terminar si el modelo no existe -con lo que envía un HTTP POST, para

crearlo- o si estamos haciendo una actualización, con lo que envía HTTP

PUT.

Finalmente, para eliminar un modelo del servidor, usaremos destroy(),

lo que genera una petición HTTP DELETE.

var contacto = new Backbone.Model({

nombre: "Justino Biever",

telefono: "+34666234567"

});

// Nos deshacemos del contactocontacto.destroy();

Obviamente, estas acciones están asociadas a los modelos que vamos

a modificar. Si queremos llevar a cabo estas acciones (por ejemplo, eli-

minar) para toda una colección, utilizamos el método de underscore.js_.each() para actuar sobre cada modelo de la colección.

46

Page 47: Primeros pasos con Backbone js, por Xavier Aznar

10 COMUNICACIÓN CON EL SERVIDOR

En esta sección he intentado clarificar un poco cómo gestiona Back-bone la comunicación del servidor. Backbone proporciona métodos es-

pecíficos para modelos y/o colecciones que permiten realizar las ope-

raciones básicas de manipulación de modelos y colecciones: fetch(),

save(), destroy(), equivalentes a las operaciones CRUD (Crear, leer

(read), actualizar (update) y destruir). Backbone es suficientemente

inteligente como para distinguir cuándo se trata de crear o actua-

lizar un modelo. Internamente estos métodos específicos delegan en

Backbone.sync. Por defecto, sync usa la función .ajax() de jQuery(o de Zepto) para comunicarse con el servidor, aunque podemos cam-

biarlo fácilmente.

Además de proporcionar la infraestructura necesaria para realizar la

comunicación con el servidor, Backbone también se encarga de dispa-

rar eventos que permiten a otras partes de nuestra aplicación reaccio-

nar ante los cambios que se produzcan en los modelos, independiente-

mente de su origen.

47