3

I am trying to add a dynamic sort by to my collection using backbone.js.

At initialization the collection has the default sorting and the view is rendered. I made a button to test how to change the sorting. It calls the following function:

app.productList.comparator = function(product) {
    return parseFloat(product.get("price"));
};
app.productList.sort();

If I understand correctly the Collection should now be sorted but the view still needs to be refreshed. I read in the documentation and in this topic to listen for the sort event

window.ProductCollection = Backbone.Collection.extend({
    model:Product,
    localStorage: new Backbone.LocalStorage("ProductCollection"),

    events:{
        "sort":"test"
    },

    test:function(){
        alert('test');
    }
});

For testing purposes I added a simple alert but this is not displayed. So it seems the sort event was not triggered.

Any ideas what I'm doing wrong here?

Community
  • 1
  • 1
Anonymoose
  • 2,389
  • 6
  • 36
  • 69

2 Answers2

4

Backbone.Collection doesn't take into account a events hash like Backbone.View does, you have to bind events yourself. You could use the initialize method to do so, something like

var ProductCollection = Backbone.Collection.extend({
    model:Product,

    initialize: function() {
        this.on('sort', this.test);
    },

    test: function(){
        console.log('test');
    }
});

And a demo http://jsfiddle.net/nikoshr/fTwpf/

nikoshr
  • 32,926
  • 33
  • 91
  • 105
1

By default there is no comparator for a collection. If you define a comparator, it will be used to maintain the collection in sorted order. This means that as models are added, they are inserted at the correct index in collection.models. A comparator can be defined as a sortBy (pass a function that takes a single argument), as a sort (pass a comparator function that expects two arguments), or as a string indicating the attribute to sort by.

"sortBy" comparator functions take a model and return a numeric or string value by which the model should be ordered relative to others. "sort" comparator functions take two models, and return -1 if the first model should come before the second, 0 if they are of the same rank and 1 if the first model should come after.

Note how even though all of the chapters in this example are added backwards, they come out in the proper order:

var Chapter  = Backbone.Model;
var chapters = new Backbone.Collection;

chapters.comparator = function(chapter) {
  return chapter.get("page");
};

chapters.add(new Chapter({page: 9, title: "The End"}));
chapters.add(new Chapter({page: 5, title: "The Middle"}));
chapters.add(new Chapter({page: 1, title: "The Beginning"}));

alert(chapters.pluck('title'));

Collections with a comparator will not automatically re-sort if you later change model attributes, so you may wish to call sort after changing model attributes that would affect the order.

Force a collection to re-sort itself. You don't need to call this under normal circumstances, as a collection with a comparator will sort itself whenever a model is added. To disable sorting when adding a model, pass {sort: false} to add. Calling sort triggers a "sort" event on the collection.

Ashwin Hegde
  • 1,733
  • 4
  • 19
  • 49