2012-02-24 56 views
19

我有点卡住实施骨干比较器,我基本上想根据路线选择不同的排序方法,并使用比较器来排序集合。理想情况下,我想将排序逻辑封装在集合中,但似乎陷入困境。例如正确实施骨干比较器

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不是一个函数”)任何想法?

+1

答案是好的,但这个问题也值得一些爱(为了得到答案):-) – jmk2142 2012-05-08 06:50:44

回答

47

这里有一些错误。

这不会做你认为它的作用:

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

即使这不适合单独努力,我也会给你+1) – ggozad 2012-02-24 19:18:13

+0

@ggozad:谢谢。我喜欢教人们如何避免错误,并帮助他们修复当前的错误。而http://jsfiddle.net/则需要付出很多努力。 – 2012-02-24 19:32:49

+0

非常感谢,非常感谢您花时间解释这一切! – Xrender 2012-02-24 19:37:02

0

我写的自定义米ethod的集合,其中将采取排序升序和降序的照顾,也还与排序的字母数字记录适当

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代表排序方法)