【问题标题】:Backbone Menu Not Sorting主干菜单未排序
【发布时间】:2015-02-10 17:06:35
【问题描述】:

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

【问题讨论】:

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


    【解决方案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 来保存单个分类模板。

    通过这种方式,您可以组合视图、更改单个分类的呈现而不更改列表并将事件范围限定到内部视图(因此单击单个分类由单个分类视图处理)。在我看来,它让一切变得更干净、更可组合和更易读。

    【讨论】:

      【解决方案2】:

      _.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}]
      

      但是,更改 key 属性时,集合不会自动重新排序。见:

      mySortedCollection.at(0).set( 'key', 3 );
      
      console.log( mySortedCollection.toJSON() );
      // [{key:3}, {a:5, key:2}]
      

      您有多种选择来解决此问题:您可以手动调用mySortedCollection.sort(),也可以通过绑定其change:key 事件来初始化集合以重新排序集合。 change:key 事件由 key 属性发生变化的模型触发。此事件会自动传播到集合。

      var AutoSortedCollection = Backbone.Collection.extend({
          comparator: 'key',
          initialize: function() {
              this.listenTo( this, 'change:key', this.sort );
          }
      });
      

      此外,我建议从模板中删除功能。调试主干视图很容易,但是当您在模板字符串中移动功能时,读取堆栈跟踪变得更加困难。您还可以通过使用 Backbone 视图来准备所有要呈现的数据,并且您的模板应该只显示它​​,从而强制执行适当的关注点分离。

      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 对它们进行迭代,并简单地引用值,而无需处理Collection 语法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-07
        • 1970-01-01
        • 2013-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多