Javascript 正确实现主干比较器
我在实现主干比较器时遇到了一些困难,我基本上希望根据路由选择不同的排序方法,并使用比较器对集合进行排序。理想情况下,我希望将排序逻辑封装在集合中,但似乎被卡住了。比如说Javascript 正确实现主干比较器,javascript,backbone.js,underscore.js,Javascript,Backbone.js,Underscore.js,我在实现主干比较器时遇到了一些困难,我基本上希望根据路由选择不同的排序方法,并使用比较器对集合进行排序。理想情况下,我希望将排序逻辑封装在集合中,但似乎被卡住了。比如说 Requests = Backbone.Collection.extend({ model : Request, comparator : function(ab) { return -ab.id; }, noof
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
。但返回排序后的列表:
nooffers : function() {
return this.sortBy(function(ab) {
return ab.get('offers');
});
}
将该列表设置为comparator函数没有任何用处
您希望更改赋值以使用函数,而不是其返回值:
if(theorder == 'nooffers') {
Request.comparator = Request.nooffers;
}
并将该函数更改为有效的比较器函数:
nooffers : function(ab) {
return ab.get('offers');
}
演示(在控制台打开的情况下运行):
但是,有人从外面摆弄收藏的方法,像这样闻起来很难闻,你不应该这样做。相反,您应该要求集合更改其顺序,如下所示:
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();
演示:
或者,您可以让集合交换自己的比较器
,以避免比较器
中的所有条件逻辑:
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”方法进行排序(仔细查看排序方法的大写字母)@ggozad:谢谢。我喜欢教人们如何避免错误以及帮助他们修复当前的错误。非常感谢,非常感谢你花了这么多时间来解释这一切@muistooshort您的jsfiddle不再工作,因为它们提供的主干似乎不再位于给定的URL。这到底是怎么回事?您是否应该更改集合的
请求
上的比较器
,而不是单个型号的请求
?但是,无论我做什么,在集合定义中设置了比较器之后,我都无法更改它。@muistooshort我有另一个CDN中的主干和下划线。我已经确认此示例和其他示例确实对集合进行了排序,但我正在使用Udacity的ToDo MVC示例,其中集合有一个addAll
方法,该方法清除列表并根据当前排序重新填充。除了sort()
之外,这就是我需要调用的。我现在正在研究这个问题。答案是好的,但这个问题也值得我们去爱(因为它引出了答案。):-)