2012-07-16 11 views

Respuesta

29

La función comparator se utiliza para comparar dos modelos en la colección y puede compararlos de cualquier forma (consistente) que desee. En particular, se puede elegir el modelo de atribuir a utilizar lo que podría tener algo como esto en su colección:

initialize: function() { 
    this.sort_key = 'id'; 
}, 
comparator: function(a, b) { 
    // Assuming that the sort_key values can be compared with '>' and '<', 
    // modifying this to account for extra processing on the sort_key model 
    // attributes is fairly straight forward. 
    a = a.get(this.sort_key); 
    b = b.get(this.sort_key); 
    return a > b ? 1 
     : a < b ? -1 
     :   0; 
}  

y luego sólo tiene algunos métodos para la recogida de cambiar el sort_key y llame sort:

sort_by_thing: function() { 
    this.sort_key = 'thing'; 
    this.sort(); 
} 

En Backbones anteriores, llamar sort activará un evento "reset", mientras que las versiones más recientes activarán un evento "sort". Para cubrir ambos casos se puede escuchar a ambos eventos y volver a hacer:

// in the view... 
initialize: function() { 
    this.collection.on('reset sort', this.render, this); 
} 

Demostración: http://jsfiddle.net/ambiguous/7y9CC/

también puede utilizar listenTo en lugar de on para ayudarle a evitar los zombies:

initialize: function() { 
    this.listenTo(this.collection, 'reset sort', this.render); 
} 

Demostración: http://jsfiddle.net/ambiguous/nG6EJ/

+0

¿Puedo utilizar este modelo en una situación en la que los campos de clasificación son cadenas – MrFoh

+0

@MrFoh: Sí, '>' y '<' trabajo en cadenas, el atributo 's' en la demostración es una cadena. –

+1

Tenga en cuenta que este ejemplo ya no funciona porque Backbone ya no dispara el evento de restablecimiento en ordenación. Dispara el evento de ordenación. –

20

La respuesta de @mu-es-demasiado-corto es buena, excepto que hay una manera más fácil de comparar el campo valores:

La forma más fácil de ordenar la colección basada en un campo, es proporcionar una función de comparación que devuelve el valor exacto del campo que desea ordenar. Este tipo de comparador hace que Backbone llame a la función sortBy, en lugar de a sort, que luego hace esa comparación compleja por sí mismo y no tiene que preocuparse por la lógica.

Por lo tanto, en esencia, no tiene que proporcionar una función de comparador compleja, a menos que tenga una necesidad más avanzada para determinar el pedido.

var myCollection = Backbone.Collection.extend({ 
    sort_key: 'id', // default sort key 
    comparator: function(item) { 
     return item.get(this.sort_key); 
    }, 
    sortByField: function(fieldName) { 
     this.sort_key = fieldName; 
     this.sort(); 
    } 
}); 

Después de esto sólo se puede llamar sortByField -función de la colección con una cadena que representa la clave que desea ordenar. Por ejemplo:

collection.sortByField('name'); 

Modified @ mi-es demasiado breve demostración de: http://jsfiddle.net/NTez2/39/

+1

Tenga en cuenta que este ejemplo ya no funciona porque Backbone ya no dispara el evento de reinicio en ordenación. Dispara el evento de ordenación. –

+1

¡Gracias por el aviso! Actualicé el ejemplo para acomodar ese cambio: http://jsfiddle.net/NTez2/39/ – jylauril

+1

El gran problema con el comparador de un solo argumento (y '_.sortBy') es que no se puede cambiar entre ordenamiento ascendente y descendente en una cuerda de cualquier manera cuerda. Descender en números es fácil ya que puede negar los números pero negar una cadena no es tan fácil. Tampoco puede ordenar por varias teclas sin mezclarlas en una sola cadena y eso se encarga de hacerlo bien. –

3

@ respuesta de jylauril ayuda a tremendamente, pero necesita modificar la demo (tal vez ligeros cambios en la columna vertebral, ya que fue publicada ?)

Parece que debe desencadenar un renderizado después de haber ordenado.

$('#by-s').click(function() { 
    c.sortByField('s'); 
    v.render(); 
}); 

Actualizado @ demostración de mi-es demasiado corta: http://jsfiddle.net/NTez2/13/

Cuestiones relacionadas