viernes, 21 de marzo de 2014

Tutorial de Backbone.js (II)


Backbone.js es una herramienta que permite separar el trabajo con datos, el trabajo de la capa visual y las acciones de navegación, lo cual hace de ésta una herramienta muy versátil a la hora de trabajar proyectos muy grandes. En la entrada anterior escribí acerca de la potencia de esta herramienta con respecto al manejo que le da a la capa de datos, en esta oportunidad veremos la manera en que se gestiona la interacción con el usuario mediante sus vistas.

Interacción con el usuario
Cuando hablamos de interacción con el usuario hacemos referencia explícita a a las vistas (Views) y a los Enrutadores (routers), en esta ocasión sólo hablaremos de las vistas. Las vistas en Backbone.js son elementos muy importantes puesto que son los encargados de presentar la información que llega del backend del servidor y permitir que los usuarios interactúen con ésta. Para esta labor se extiende la clase Backbone.View, veamos un ejemplo.

var ViewLibro = Backbone.View.extend({
    events:{
        "click a#delete" : "eliminar",
    },
    initialize : function () {
        this.template = _.template(
                 $('#templatelibro').html()
                 );
    },
    render : function() {
        var data = this.model.toJSON();
        var html = this.template(data);
        this.$el.append( html );
    },
    eliminar: function(e) {
        this.model.url = this.model.url+this.model.id;
        this.model.destroy();
        var libro = $(e.currentTarget).parent().parent();
        libro.remove();
        e.stopPropagation();
    }
});

Además hacemos unos pequeños cambios a la función listarLibros
function listarLibros () {
    $(".datos").html("")
    var coleccion_libros = new Libros();
    coleccion_libros.on("add", function(model){
        console.log("Agregado", model.toJSON());
        var vl = new ViewLibro({el:$("ul.datos"),model:model});
        vl.render();
    });
    var xhr = coleccion_libros.fetch()
    xhr.done(function () {
        console.log('Libros descargados...');
        var llibros = coleccion_libros.filter(function (model) {
            var libro = model.toJSON();
            return libro.nombre === "El Principito";
        });
        if(llibros.length==0){
            var libroNuevo = new Libro({
                "nombre":"El Principito",
                "editorial":"Panamericana",
                "genero":"Infantil",
                "autor":"1"
            });
            libroNuevo.save();
            libroNuevo.attributes.id = 1;
            coleccion_libros.add(libroNuevo);
        }
        console.log("0k");
    });

}

Y finalmente agregamos el template respectivo
<script type="text/template" id="templatelibro">
    <div id="libro-<%= id %>" class="libro">
        <strong>Nombre:</strong> <%= nombre %> <br/>
        <strong>Editorial:</strong> <%= editorial %><br/>
        <strong>Genero:</strong> <%= genero %><br/><br/>
        <div class="actions">
            <a href="#" id="delete">Eliminar Libro</a>
        </div>
    </div>
</script>
Muy bien, pero ¿Qué hace todo esto? Primero construimos la vista, para esto hacemos una clase que hereda de Backbone.View, esta tiene una serie de elementos que hacen posible toda la "magia" que hace internamente, el primero es el objeto events, el cual almacena el tipo de evento (por ejemplo click) y sobre que elemento del DOM se aplica, para esto usamos "." (punto) para especificar clases y y "#" para especificar los identificadores. Asociado a esto se encuentra el nombre del método que se ejecutará cuando el evento sea llevado a cabo.
Luego encontramos el método initialize, que inicializa la vista, adentro de este creamos el template de la vista, debemos tener en cuenta que el carácter "_" hace referencia a la librería Underscore.js, también creada por Jeremy Ashkenas, creador de Backbone.js, la cual tiene una serie de herramientas muy útiles y una de estas es un sistema de templates. Cabe aclarar que no es obligatorio usar el sistema de templates de underscore, su puede usar el que se desee (swig, mustache, etc).
Después encontramos el método render, que toma los datos del modelo y los renderiza con el template creado en el método initialize para finalmente mostrarlo al usuario en el lugar de destino, referido por la variable de clase $el.
Como último elemento de la vista encontramos el método eliminar, que actualiza la url del modelo, llama el método eliminar y retira el HTML asociado al modelo del DOM.

Dentro de la función listar libros encontramos que ya no creamos el código HTML necesario para incrustar en el DOM, en cambio creamos una instancia de la vista y la renderizamos y al crear en nuevo libro especificamos como atributo el id de ese nuevo objeto.

Finalmente esta el código del template asociado a la vista, notese que éste se guarda en un tag script de tipo text/template y tiene un identificador para poder recuperarlo con Javascript.

No hay comentarios:

Publicar un comentario