correctly implement backbone comparators

You have a few things wrong here.

This doesn’t do what you think it does:

if(theorder == 'nooffers') {
    Request.comparator = Request.nooffers();
}

That executes the nooffers method and assigns its result to Request.comparator. But sortBy returns the sorted list:

nooffers : function() {
    return this.sortBy(function(ab) {               
        return ab.get('offers');
    });
}

and setting that list as the comparator function doesn’t do anything useful.

You want to change the assignment to use the function rather that its return value:

if(theorder == 'nooffers') {
    Request.comparator = Request.nooffers;
}

and change the function to be a valid comparator function:

nooffers : function(ab) {
    return ab.get('offers');
}

Demo (run with your console open): http://jsfiddle.net/ambiguous/AAZCa/

But having someone from the outside fiddling with the collection’s methods like that smells bad and you shouldn’t do it. Instead, you should ask the collection to change its ordering with something like this:

var Requests = Backbone.Collection.extend({
    model: Request,
    comparator: function(ab) {
        if(this._order_by == 'offers')
            return ab.get('offers');
        else if(this._order_by == 'id')
            return -ab.id;
        //...
    },
    order_by_offers: function() {
        this._order_by = 'offers';
        this.sort();
    },
    order_by_default: function() {
        this._order_by = 'id';
        this.sort();
    },
    _order_by: 'id'
});
//...
rs.order_by_offers();

Demo: http://jsfiddle.net/ambiguous/uM9av/

Or you could let the collection swap its own comparator to avoid all the conditional logic inside the comparator:

var Requests = Backbone.Collection.extend({
    model: Request,
    initialize: function() {
        this._order_by_id = this.comparator;
    },
    comparator: function(ab) {
        return -ab.id;
    },
    order_by_offers: function() {
        this.comparator = this._order_by_offers;
        this.sort();
    },
    order_by_default: function() {
        this.comparator = this._order_by_id;
        this.sort();
    },
    _order_by_offers: function(ab) {
        return ab.get('offers');
    }
});

Demo: http://jsfiddle.net/ambiguous/Pjfq2/

Leave a Comment