バックボーンコンパレータの実装が少し行き詰まっています。基本的に、ルートに基づいてさまざまな並べ替え方法を選択し、コンパレータを使用してコレクションを並べ替えたいと思います。理想的には、ソートロジックをコレクション内にカプセル化したままにしておきたいのですが、行き詰まっているようです。例えば
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は関数ではありません」)。
ここでいくつか間違っていることがあります。
これはあなたが思っていることをしません:
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');
}
});
コレクションにカスタムメソッドを記述しました。これは、昇順と降順の両方の並べ替えを処理し、英数字でレコードを適切に並べ替えます。
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をよく見てください)