web-dev-qa-db-de.com

backbone-Komparatoren korrekt implementieren

Ich bin ein wenig festgefahren, einen Backbone-Komparator implementiert. Ich möchte grundsätzlich verschiedene Sortiermethoden basierend auf der Route auswählen und den Komparator zum Sortieren der Sammlung verwenden. Im Idealfall möchte ich die Sortierlogik in der Sammlung einkapseln, aber scheinbar stecken bleiben. Zum Beispiel

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

Standardmäßig wird es nach dem Standardvergleicher sortiert - aber in meinem Routing möchte ich z. so etwas tun

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

In diesem Fall bekomme ich jedoch eine Fehlermeldung ('c.call ist keine Funktion'). Ideen? 

21
Xrender

Sie haben hier ein paar Dinge falsch.

Dies tut nicht das, was Sie denken:

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

Dadurch wird die Methode nooffers ausgeführt und das Ergebnis Request.comparator zugewiesen. Aber sortBy gibt die sortierte Liste zurück:

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

wenn Sie diese Liste als Komparatorfunktion einstellen, ist dies nicht sinnvoll.

Sie möchten die Zuweisung ändern, um die Funktion und nicht deren Rückgabewert zu verwenden:

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

und ändern Sie die Funktion, um eine gültige Komparatorfunktion zu sein:

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

Demo (bei geöffneter Konsole ausführen): http://jsfiddle.net/ambiguous/AAZCa/

Wenn jemand von außen mit den Methoden der Sammlung herumfummelt, riecht das schlecht, und Sie sollten es nicht tun. Stattdessen sollten Sie die Sammlung bitten, ihre Reihenfolge mit etwas wie dem folgenden zu ändern:

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/

Oder Sie lassen die Collection einen eigenen comparator austauschen, um die gesamte bedingte Logik in comparator zu vermeiden:

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/

50
mu is too short

Ich habe eine benutzerdefinierte Methode in der Sammlung geschrieben, die sowohl das Auf- als auch das Absteigend sortieren und Datensätze mit alphanumerischen Zeichen entsprechend sortieren wird

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

// Sie können sortieren, indem Sie die "Sort" -Methode verwenden.

0