正确实现主干比较器

IT技术 javascript backbone.js underscore.js
2021-03-15 05:59:13

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

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

因此,默认情况下,它根据默认比较器进行排序 - 但在我的路由中,我希望能够诉诸例如做类似的事情

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

但是,在这种情况下,我收到错误消息('c.call 不是函数')有什么想法吗?

2个回答

你这里有一些问题。

这不会像你认为的那样做:

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

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

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

并将该列表设置为比较器函数并没有做任何有用的事情。

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

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

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

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

演示(在打开控制台的情况下运行):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();

演示: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');
    }
});

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

@ggozad:谢谢。我喜欢教人们如何避免错误以及帮助他们修复当前的错误。jsfiddle.net需要很多的努力了。
2021-04-21 05:59:13
非常感谢,非常感谢您花时间解释所有这些!
2021-05-01 05:59:13
@muistooshort 您的 JSFiddles 不再工作,因为它们提供的 Backbone 似乎不再位于给定的 URL。无论如何,这将如何运作?您不应该为集合而不是单个模型更改comparatoron吗?但是,无论我做什么,我都无法在集合定义中设置它之后更改它。RequestsRequestcomparator
2021-05-09 05:59:13
@muistooshort 我有一个来自另一个 CDN 的 Backbone 和Underscore示例的分支我已经确认这个示例和其他示例确实对集合进行了排序,但我正在使用 Udacity 的 ToDo MVC 示例,其中集合有一个addAll方法可以清除列表并根据当前排序重新填充它。除了sort(). 我现在可以在我的 ToDo 示例版本中使用此功能
2021-05-12 05:59:13

我在集合中编写了自定义方法,它将负责对升序和降序进行排序,并且它还可以适当地使用字母数字对记录进行排序

var LetterVariables = Backbone.Collection.extend({



    initialize: function (id) {

        //id of the table
        this.id = id;

        this.sortVar = "id"; //default sorting column
        this.sOrder = "asc" //default sort order
    },
    //comparator function that will create a descending and an ascending order tot he view
    comparator: function (item,itemb) {
        var a=item.get(this.sortVar);
        var b=itemb.get(this.sortVar);
        if (this.sOrder == "asc") {
            return this.SortCustom(a, b);
        }
        return -this.SortCustom(a, b);
    },
    SortCustom:function(a,b){
                if (isNaN(a)) {
                    if (isNaN(b)) {
                        if (a > b) return 1; // before
                        if (b > a) return -1; // after
                        return 0;
                    }
                    return 1;
                }
                if (isNaN(b)) {
                    return -1;
                }
                if (+a > +b) return 1; // before
                if (+b > +a) return -1; // after
                return 0;
    },
    Sort: function (by, order) {

        this.sOrder = order;
        this.sortVar = by;
        this.sort();
    }});

//您可以使用“Sort”方法进行排序(请仔细查看Sort方法的大写S)