Desarrollo móvil multiplataforma
 

Tutorial de Backbone.js – III. Colecciones

Tutorial de Backbone.js – III. Colecciones

Introducción

Tras haber analizado los modelos en el tema anterior, en este tema vamos a ver las colecciones, que no son otra cosa que conjuntos ordenados de instancias de modelos.

Normalmente una colección contendrá instancias de un único modelo, aunque realmente no hay restricción alguna y una colección podría contener instancias de distintos modelos.

Creación de colecciones

Como ocurría en los modelos, podemos crear una colección extendiendo el objeto Backbone.Collection donde especificaremos el modelo que asociaremos con él:

Clientes = Backbone.Collection.extend({
    model: Cliente
});

Al igual que los modelos, las colecciónes también disponen de una función initialize que podremos implementar en la definición de la colección. De igual manera el método extend admite un segundo parámetro opcional para poder indicar ciertas propiedades a nivel de clase.

Indicar el modelo asociado en el comando extend sirve para que podamos añadir objetos a la colección indicando simplemente los atributos, y será la colección la que se encargará de convertirlos a instancias del modelo:

var clientes = new Clientes([{nombre:'Alfonso', apellidos:'Marín'}, 
                             {nombre:'Javier', apellidos:'Serrano'}]);

Como vemos, podemos crear una instancia de la colección indicando un array de objetos hash que serán convertidos a instancias del modelo asociado (Cliente) y formarán parte de la colección. Este array de objetos es opcional, pues podemos añadir objetos posteriormente utilizando add :

var clientes = new Clientes();
clientes.add([{nombre:'Alfonso', apellidos:'Marín'}, 
              {nombre:'Javier', apellidos:'Serrano'}]);

También podemos utilizar el método remove para eliminar objetos de la colección indicándole la instancia o array de instancias a eliminar.

Por último, existe la función reset que eliminará toda instancia existente en la colección y la sustituirá por las instancias que esta función reciba como parámetro. Si no se le pasa ningún array de instancias, este comando vacía completamente la colección.

Recuperar objetos de la colección

Para recuperar una instancia determinada podemos buscar por sus identificadores o por su posición:

//La función get buscará la instancia cuyo id sea el que le pasamos como parámetro
clientes.get("id-de-cliente");
// La función getByCid buscará la instancia cuyo cid sea el que le pasamos como parámetro
clientes.getByCid('valor-cid');
// La función at buscará la instancia situada en la posición pasada como parámetro
clientes.at(1)

Al igual que ocurría en los modelos con la propiedad attributes, los objetos Collection tienen una referencia directa al array de modelos asociados a la colección llamada models, siendo un candidato ideal sobre el que utilizar toda la potencia de los métodos de la librería underscore.js. Un ejemplo:

// filter: itera sobre el array o hash pasando los elementos a una función callback
// Devuelve un array o hash con los elementos que hayan devuelto 'true' en la función callback
var clientes_jubilados = _.find(clientes.models, function(cliente){ return cliente.edad > 65 });

Eventos

Las colecciones generan un evento add o remove cada vez que se añade o elimina un elemento a la colección, respectivamente. Además por convenio cada evento que se genere en alguno de los modelos de la colección se generará también en la colección directamente. De esta forma, una colección podría capturar los eventos change:atributo de forma que sería notificada cada vez que cambia dicho atributo en alguno de los modelos que la componen.

También se genera un evento reset cuando se ejecuta dicho comando sobre la colección.

Ordenación

Por defecto, las colecciones mantienen los modelos desordenados y los guardan según su orden de inserción. Si quisiéramos mantener ordenada la colección, podríamos definir la función comparator a la hora de definir el modelo. Esta función recibirá un modelo como parámetro y deberá devolver un número o una cadena de caracteres por la que se ordenará la colección, ya sea numéricamente o alfabéticamente.

Clientes = Backbone.Collection.extend({
    comparator: function(cliente){
        // ordenamos por el atributo nombre
        return cliente.get('nombre');
    }
    // ...
});

Si una colección tiene definida la función comparator permanecerá ordenada en todo momento ya que cada vez que se inserte una nueva instancia de modelo la colección ejecutará el proceso de ordenación. Normalmente se hace de forma automática, pero aún así existe un método llamado sort que forzaría la ejecución del proceso de ordenación. Este método también generaría el evento reset.

Resumen

Hemos descubierto las colecciones, aprendido cómo añadir, eliminar y buscar elementos. También hemos aprendido qué eventos generan las colecciones y que podemos ordenarlas si queremos. Todavía quedan algunas funciones por ver, pero están más relacionadas con la sincronización y la persistencia en el servidor. Por ese motivo los analizaremos más adelante.

En el siguiente tema abordaremos la parte más visual del Backbone: las vistas.

  1. Ale Prieto March 3, 2013

    ¡gracias!

  2. Gaspar Fernández March 6, 2013

    Hola,
    Estoy siguiendo el tutorial, y no he podido resistirme… Espero que no te lo tomes como algo ofensivo… Tienes un ejemplo donde pones clientes_juvilados, esa palabra es con b.

    Eso sí, felicidades por el tutorial, muy detallado, estoy siguiéndolo y la cosa va bien por ahora 🙂

  3. Ivang April 15, 2013

    Muy gratificante el encontrar un tutorial en español que aborda la explicación de un framework de manera que parece incluso muy sencillo el usar backbone. Comparado con otros, el ir de lo más elemental y transversal a lo más complicado es de lo más acertado.
    Gracias por el tutorial!

    P.D. El párrafo de los eventos sobre colecciones me queda algo confuso: Cuando en una colección se agrega o modifica una _instancia_ de modelo dices que la colección genera el evento change/add sobre todos los modelos que hay en la colección, pero al decir que se pueden mezclar modelos, no me queda claro si el evento se genera sobre cada una de las instanacias de _cualquier_ modelo o únicamente sobre las instancias del mismo modelo a partir del cual se ha generado el evento change/add. A lo mejor no me he explicado bien, pero es que no me ha quedado muy claro. Gracias anticipadas por la aclaración.

  4. Armando Garcia June 13, 2014

    En el ejemplo de ordenacion, no seria:
    return cliente.get(‘nombre’);
    ?