我无法正确排序Backbone集合。我继承了这个项目,所以在其他地方可能会有一些恶作剧,但我想排除任何语法错误。
该项目使用JSON文件来处理数据:
"classifications": [
{
"name": "1 Bedroom",
"alias": "1BR",
"id": "1BR",
"menu_desc": "Residences"
},
{
"name": "2 Bedroom",
"alias": "2BR",
"id": "2BR",
"menu_desc": "Residences"
},
{
"name": "3 Bedroom",
"alias": "3BR",
"id": "3BR",
"menu_desc": "Residences"
},
{
"name": "4 Bedroom",
"alias": "4BR",
"id": "4BR",
"menu_desc": "Residences"
},
{
"name": "Common Areas",
"alias": "Common",
"id": "Common",
"menu_desc": "Resident Amenities"
}
]
以前,没有单卧室单位,它呈现的顺序是:
我添加了单卧室分类,突然命令是这样的:
我做了一些挖掘并找到了有关比较器属性的文档,但它似乎只适用于集合。该项目没有使用集合进行分类。它适用于子菜单项(单位所在的楼层等),但不适用于主菜单:
var MenuClassificationListView = Backbone.View.extend({
id: "classification_accordion",
template: _.template( "<% var classifications = this.options.classifications; _.each(this.collection.attributes, function(v,k) { %>"+
"<h3 class='<%= k %>'><%= classifications.get(k).get('name') %>"+
"<p><%=classifications.get(k).get('menu_desc')%></p></h3>"+
"<% var model = new MenuClassificationList(v); var view = new MenuClassificationItemView({collection:model, classification:k}); %>"+
"<% print(view.render().el.outerHTML); %>"+
"<% }); "+
"%>"),
render: function(){
//console.log(this.options.classifications);
//console.log(this.collection.attributes);
//alert(1);
this.$el.html(this.template());
return this;
}
});
如何合并比较器?
谢谢,
TY
答案 0 :(得分:1)
一种方法是为分类定义一个集合,就像你提到的其他项目一样:
var Classifications = Backbone.Collections.extend({ // etc. etc.
这样你可以添加比较器,它将始终被排序。
另一种方法是在视图的initialize
函数中对数组进行排序(http://underscorejs.org/#sortBy:
initialize: function(options) { // sorry don't remember the exact syntax for the parameters passed in, but I believe options is what you need
this.options.sortedclassifications = _sortBy(options.classifications, function (c) { return parseInt(c.id); }); // or any other sorting logic
}
然后在template
中使用已排序的分类:
template: _.template( "<% var classifications = this.options.sortedclassifications; _.each(this.collection.attributes, function(v,k) { %>" + // etc. etc.
这应该可以满足您的需求。但是,如果我可以添加个人意见,我会努力为分类定义集合,并为单一分类定义模型。此外,我会保留MenuClassificationListView
,但也会创建一个MenuClassificationView
来保存单个分类模板。
通过这种方式,您可以组合视图,更改单个分类的渲染而无需更改列表并将事件范围限定为内部视图(因此单个分类视图可以处理单个分类的处理)。在我看来,它使一切更清晰,更具组合性和可读性。
答案 1 :(得分:0)
_。sortBy不需要使用,因为Backbone集合已经内置了排序功能。
请参阅:http://backbonejs.org/#Collection-comparator
示例:
var SortedCollection = Backbone.Collection.extend({
comparator: 'key'
});
var mySortedCollection = new SortedCollection([{a:5, key:2}, {key:1}]);
console.log( mySortedCollection.toJSON() );
// [{key:1}, {a:5, key:2}]
但是,更改键属性时,不会自动重新排序集合。参见:
mySortedCollection.at(0).set( 'key', 3 );
console.log( mySortedCollection.toJSON() );
// [{key:3}, {a:5, key:2}]
您有多种方法可以解决此问题:您可以手动调用mySortedCollection.sort()
,也可以通过绑定其change:key
事件来重新排序集合来初始化集合。 change:key
事件由其键属性更改的模型触发。此事件将自动传播到集合。
var AutoSortedCollection = Backbone.Collection.extend({
comparator: 'key',
initialize: function() {
this.listenTo( this, 'change:key', this.sort );
}
});
此外,我建议从模板中删除功能。调试Backbone Views很容易,但在模板字符串中移动功能时,更难以读取堆栈跟踪。您还可以通过使用Backbone View准备所有数据进行演示来强制正确分离关注点,您的模板应该只显示它。
var MyView = Backbone.View.extend({
//...
serializeData: function() {
return {
classifications: this.collection.toJSON(),
keys: this.collection.length > 0 ? this.collection.at(0).keys() : []
}; // already sorted
}
render: function() {
this.$el.html(this.template( this.serializeData() ));
}
});
您的模板字符串变得更容易阅读:您可以直接使用变量classifications
和keys
,使用_.each
进行迭代,只需引用值而无需处理集合语法。