主干菜单未排序

时间:2015-02-10 17:06:36

标签: javascript sorting backbone.js backbone-views comparator

我无法正确排序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"
            }
        ]

以前,没有单卧室单位,它呈现的顺序是:

original order

我添加了单卧室分类,突然命令是这样的:

incorrect order

我做了一些挖掘并找到了有关比较器属性的文档,但它似乎只适用于集合。该项目没有使用集合进行分类。它适用于子菜单项(单位所在的楼层等),但不适用于主菜单:

    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

2 个答案:

答案 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() ));
    }
});

您的模板字符串变得更容易阅读:您可以直接使用变量classificationskeys,使用_.each进行迭代,只需引用值而无需处理集合语法。