Backbone: reverse sort order of models in a collection

Created on 11 Apr 2011  ·  12Comments  ·  Source: jashkenas/backbone

hey,

what's the best way to reverse the sort order a collection? my comparator sorts all models by date,
but i would need them in reverse order. using toArray() and reverse() seems pretty ugly.

given i'm not missing something important here, i'd vote for a backbone model attribute to set the
sort order along with the comparator.

cheers,
daniel

question

Most helpful comment

You could also do

collection.set(collection.models.reverse(), {sort: false});

All 12 comments

The best way to reverse the sort of the collection is to return a negative value from your comparison criterion.

comparator : function(model) {
  return -model.get('date');
}

How is this supposed to work when sorting alphabetically on a string value?

If all you have are string values, then maybe convert to a Date before?
I had the same problem and this solved it.

comparator : function(model) {
  return -new Date(model.get('date'));
}

That only works for dates (which are converted into numbers when you prefix them with -), but not for arbitrary strings that you want to sort alphabetically.

You're of course right, I assumed you were still talking about dates (like the OP), but that your date was a convertible string. My mistake then :).

The next version of Backbone (and the current master) will support sort orderings for comparators (instead of just sortBy), so you'll be able to define it in the usual way.

comparator: function(a, b) {
  ...
}

What do you do if you have multiple use-cases for the same collection, some of which should be shown in one order, and the other in the reverse? Your comparator and sort implementations can only pick one direction or the other, there doesn't seem to be a Collection.reverse() to be able to quickly switch sort directions (ascending vs descending).

@elwayman02 You can just maintain 2 collection instances (Collection#clone may help)

That's not particularly useful...take for example a situation where the collection represents a grid of data that I will be repeatedly sorting in multiple directions. It doesn't make sense to try and maintain two different sources of data and switch between them. There should be one data object that we manipulate as needed.

I've stored multiple comparators on a collection, and swapped them out as needed.

var Collection = Backbone.Collection.extend({
  comparators: {
    a: function () {},
    b: function () {}
  },

  setComparator: function (key) {
    this.comparator = this.comparators[key];
    return this;
  }
});
var collection = new Collection();
collection.setComparator('a').sort();
collection.setComparator('b').sort();

That's a better workaround, although I still don't understand why a workaround is necessary instead of backbone simply supporting a reverse() method.

You could also do

collection.set(collection.models.reverse(), {sort: false});
Was this page helpful?
0 / 5 - 0 ratings