代码之家  ›  专栏  ›  技术社区  ›  Sander Marechal

如何在项之间呈现具有标题的Backbone集合

  •  0
  • Sander Marechal  · 技术社区  · 9 年前

    我的应用程序中有一个基本上是时间线的主干集合。集合中的每个项目都有 date 字段,集合按其排序。项目将动态加载并添加到此集合(滚动时)。

    我想呈现这个集合,但我还需要呈现一个 <div> 在项目之间作为日标题。例子:

    [{"date": new Date("2015-01-02T12:00"),
      "text: "Message 4"},
     {"date": new Date("2015-01-02T06:00"),
      "text: "Message 3"},
     {"date": new Date("2015-01-01T23:00"),
      "text: "Message 2"},
     {"date": new Date("2015-01-01T20:00"),
      "text: "Message 1"}
    ]
    

    我想呈现如下内容:

    <div class="timeline">
      <div class="day">2015-01-02</div>
      <div class="message">Message 4</div>
      <div class="message">Message 3</div>
      <div class="day">2015-01-01</div>
      <div class="message">Message 2</div>
      <div class="message">Message 1</div>
    </div>
    

    或者像这样(嵌套):

    <div class="timeline">
      <div class="day">2015-01-02
        <div class="message">Message 4</div>
        <div class="message">Message 3</div>
      </div>
      <div class="day">2015-01-01
        <div class="message">Message 2</div>
        <div class="message">Message 1</div>
      </div>
    </div>
    

    我一直在看 Backbone.Projections 但我似乎需要手动创建大量过滤的集合(每天一个集合),然后将所有这些日常集合放到另一个集合中。

    我还看过 Backbone.Collection.groupBy 但我不知道如何使用它来渲染视图,更不用说如何在时间线中添加新项目时保持组的更新。

    有没有一种好的方法来呈现这样的时间线集合?有什么插件可以帮助你吗?

    1 回复  |  直到 9 年前
        1
  •  1
  •   nikoshr    9 年前

    Backbone的优点之一是它不会强制您使用预定义的模式。在您的案例中,您可以按天对模型进行分组,为每个组生成HTML,然后将结果推送到DOM。

    为了方便起见,假设您的模型和集合是这样定义的:

    var M =  Backbone.Model.extend({
        day: function() {
            var d = this.get('date'), 
                month = d.getMonth()+1,
                day = d.getDate();
            if (month<10) month = '0'+month;
            if (day<10) day = '0'+day;
    
            return [d.getFullYear(), month, day].join('-');
        }
    });
    var C = Backbone.Collection.extend({
        model: M
    });
    

    您的视图可能看起来像

    var V = Backbone.View.extend({
        render: function() {
            var rows;
    
            rows = this.collection.chain().groupBy(function (m) {
                return m.day();
            }).map(function (models, dt) {
                // you would use a template here
                // hard coded strings will do for now
    
                var html = '<div class="day">' + dt + '</div>';
                _.each(models, function (m) {
                    html+= '<div class="message">' + m.get('text') + '</div>';
                });
    
                return html;
            }).value();
    
            this.$el.html(rows.join(''));
        }
    });
    

    还有一只小提琴 http://jsfiddle.net/nikoshr/swbm8ax5/4/