Подтвердить что ты не робот

Правильно применять опорные компараторы

Я получаю немного застрял, реализованный компоновщик магистральных ячеек, я в основном хочу выбрать различные методы сортировки на основе маршрута и использовать компаратор для сортировки коллекции. В идеале я хочу сохранить логику сортировки, инкапсулированную внутри коллекции, но, похоже, застревает. Например

    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 не является функцией" ) какие-либо идеи?

4b9b3361

Ответ 1

У вас здесь несколько вещей.

Это не делает то, что вы думаете:

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/

Ответ 2

Я написал собственный метод в коллекции, который будет заниматься сортировкой как по восходящей, так и по убыванию, а также сортирует записи с буквенно-цифровым соответствием

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();
    }});

//вы можете сортировать с помощью метода "Сортировка" (посмотрите в верхнем регистре S для метода Sort)