Sorting a Backbone Collection After initialization

62,246

Solution 1

There's a discussion on this very topic that you might want to look at: https://github.com/documentcloud/backbone/issues/41.

The short of it is that when a user selects 'sort by X', you can:

  1. Set the comparator function on the Collection
  2. Call the Collection's sort function (which will trigger a sort event)
  3. Listen for the sort event in your View, and (clear and) redraw the items

Another way to handle steps 1 & 2 is to have your own method that calls the Collection's sortBy method and then triggers a custom event that your View can listen to.

But it seems to be the case that clearing and redrawing is the easiest (and maybe even the fastest) way to sort your View's and keep them in sync with your Collection's sort order.

Solution 2

You can update the comparator function and then call the sort method.

// update comparator function
collection.comparator = function(model) {
    return model.get('name');
}

// call the sort method
collection.sort();

The view will be automatically re-rendered.

Solution 3

comparator is what you need

var PhotoCollection = Backbone.Collection.extend({
    model: Photo,
    comparator: function(item) {
        return item.get('pid');
    }
});

Solution 4

This way works well and enables sorting by all attributes dynamically and handles ascending or descending:

var PhotoCollection = Backbone.Collection.extend({
    model: Photo,
    sortByField: function(field, direction){
            sorted = _.sortBy(this.models, function(model){
                return model.get(field);
            });

            if(direction === 'descending'){
                sorted = sorted.reverse()
            }

            this.models = sorted;
    }
});
Share:
62,246
Jhony Fung
Author by

Jhony Fung

I am a tech geek who loves to explore new technology. Writing code, building applications, and debugging problems are things I enjoy doing. I co-founded CityPockets.com and currently working full time on it.

Updated on July 09, 2022

Comments

  • Jhony Fung
    Jhony Fung almost 2 years

    I am using Backbone.js to render a list of items e.g Books. After the list is rendered, there are options for user to sort them. So if user clicks on Sort By Title, or Sort By Author Name the list will sort itself on the client side.

      window.Book = Backbone.Model.extend({
       defaults: {
         title: "This is the title",
         author: "Name here"
       },
    

    What is the best way to accomplish this sort using in the context of a Backbone application. Do I use a jQuery dom sorter in the AppView?

  • Jhony Fung
    Jhony Fung over 12 years
    Isn't comparator used for sorting the collection during initialization. After the list has been displayed, the user have actions to re-sort them in different ways and that's what I need to figure out.
  • Jhony Fung
    Jhony Fung over 12 years
    Thanks rulfzid. I am going to try this approach out
  • Kirby
    Kirby almost 12 years
    and then how does one do descending?
  • Kirby
    Kirby almost 12 years
    .. found it... use a minus sign 'return -model.get('name');'
  • CheapSteaks
    CheapSteaks about 11 years
    Correction for 2. the sort event is the one that gets fired when the Collection's sort function is called, not reset
  • Fasani
    Fasani over 10 years
    In your view you need to listen to the 'sort' event not 'reset' (I think that's older versions of backbone). Pass the same collection to the view and use: this.listenTo(this.collection, 'sort', this.render);
  • benjaminz
    benjaminz over 8 years
    Will that create a ton of zombie views? It seems that every time you "sort" you are creating new Backbone view objects which takes additional time and space and leaving old view objects hanging around.
  • Leo Romanovsky
    Leo Romanovsky over 8 years
    multiply by -1 in the sort function to avoid sorting twice.
  • Roberto
    Roberto about 8 years
    @Leo that would only be useful if field is numeric
  • Jyothu
    Jyothu almost 8 years
    After sorting, I have empty values are coming on the top. How can I move these empty values to the bottom ?
  • Loourr
    Loourr almost 8 years
    @Jyothu I would recommend either removing the empty items from your collection or sorting over a fields which denotes the empty values by some index, which gets sorted to the bottom.
  • pioto
    pioto about 7 years
    @Kirby, I would think that descending order with a - sign would only work for Number attributes, not String ones?