正确实现骨干比较器

Xre*_*der 21 javascript backbone.js underscore.js

我有点卡住实现了骨干比较器,我基本上想要根据路由选择不同的排序方法,并使用比较器对集合进行排序.理想情况下,我希望将排序逻辑封装在集合中,但似乎陷入困境.例如

    Requests = Backbone.Collection.extend({
        model : Request,
        comparator : function(ab) {
            return -ab.id;
        },          
        nooffers : function() {
            return this.sortBy(function(ab) {               
                 return ab.get('offers');
            });
        }
    }); 
Run Code Online (Sandbox Code Playgroud)

因此,默认情况下,它会根据默认比较器进行排序 - 但在我的路由中,我希望能够采取类似的措施

   routes : {
        "" : "index",
        '/ordering/:order' : 'ordering'
    },
    ordering : function(theorder) {
        ordering = theorder;
        if(theorder == 'nooffers') {
            Request.comparator = Request.nooffers();
        }
        Request.sort();
        listView.render();  
        howitworksView.render();
    }
Run Code Online (Sandbox Code Playgroud)

但是在那种情况下,我得到一个错误('c.call不是函数')任何想法?

mu *_*ort 50

你这里有一些错误.

这不符合你的想法:

if(theorder == 'nooffers') {
    Request.comparator = Request.nooffers();
}
Run Code Online (Sandbox Code Playgroud)

执行该nooffers方法并将其结果分配给Request.comparator.但是sortBy返回排序列表:

nooffers : function() {
    return this.sortBy(function(ab) {               
        return ab.get('offers');
    });
}
Run Code Online (Sandbox Code Playgroud)

并将该列表设置为比较器功能并没有做任何有用的事情.

您想要更改赋值以使用该函数而不是其返回值:

if(theorder == 'nooffers') {
    Request.comparator = Request.nooffers;
}
Run Code Online (Sandbox Code Playgroud)

并将该函数更改为有效的比较器函数:

nooffers : function(ab) {
    return ab.get('offers');
}
Run Code Online (Sandbox Code Playgroud)

演示(在控制台打开的情况下运行):http://jsfiddle.net/ambiguous/AAZCa/

但是,让外面的人摆弄集合的方法,就像那些闻起来很糟糕,你不应该这样做.相反,你应该让集合改变它的顺序,如下所示:

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();
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/ambiguous/uM9av/

或者您可以让集合交换它自己comparator以避免以下内部的所有条件逻辑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');
    }
});
Run Code Online (Sandbox Code Playgroud)

演示:http://jsfiddle.net/ambiguous/Pjfq2/

  • 即使这不适合单独的努力,我也会给你+1;) (2认同)