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?
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');
}
});
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.