【问题标题】:Display item in Marionette CollectionView that's not member of the collection?在 Marionette CollectionView 中显示不是集合成员的项目?
【发布时间】:2015-11-04 21:59:08
【问题描述】:

我有一个 Marionette CollectionView,其中每个 childViews 都以网格方式浮动(其中每个 X 是 childView):

X X X X
X X X 

我希望有一个浮动在网格中的加号按钮,但实际上并不代表集合中的项目。所以它看起来像这样:

X X X X
X X X +

是否有人对如何使用 Marionette 完成此操作有想法或策略?

【问题讨论】:

    标签: marionette


    【解决方案1】:

    我们在我们的应用程序中正是这样做的。为了实现它,我们有一个复合视图,其模板如下:

    <div class='my-composite-view'>
      <div class='my-child-view-container'>
      </div>
      <div class='my-plus-button'>
      </div>
    </div>
    

    只要你浮动my-child-view-container中的所有div,然后浮动my-plus-button div,你就会得到你想要的。

    http://jsfiddle.net/cn1gp4m4/

    【讨论】:

      【解决方案2】:

      虽然您可以手动添加 html 元素,但如果我需要在视图中显示除集合之外的任何内容,我将移至 CompositeView。 CompositeView 将在模板内的给定容器中维护集合视图,因此您可以在与集合相同的视图中包含任何元素。

      但是 CompositeView 不允许您在集合容器中拥有其他元素作为集合视图项的兄弟。如果你真的需要你自己的元素作为集合视图项的兄弟,你可以手动添加它,如下所示。但我肯定会使用 CompositeView 来保持 html 结构的整洁。

      这个例子展示了你实际上可以手动添加元素,用 CSS 放置你想要的任何位置。 Marionette 不会删除您手动添加的元素,因为它不会真正重新渲染自己,它只是在子视图被添加或从集合中删除时添加和删除。

      var ItemView = Mn.ItemView.extend({
        template: _.template('<%=title%> (<a href="#">remove</a>)'),
        events: { 'click a': 'rm' },
        rm: function(evt){
          this.model.collection.remove( this.model );
        }
      });
      
      var col = new Backbone.Collection([
        {title: 'Espresso'},
        {title: 'Cappuccino'},
        {title: 'Caffe Latte'}
      ]);
      col.counter = 0;
      
      var colview = new Mn.CollectionView({
        collection: col,
        className: 'Collection',
        childView: ItemView
      });
      
      var $add = $('<div class="add">+</div>').click(function(){
        col.add({ title: 'Coffee #'+(++col.counter) });
      });
      colview.$el.append($add);
      
      colview.render().$el.appendTo(document.body);
      
      col.add({title:'Americano'});
      col.remove( col.at(1) );
      div {
        border: 1px solid gray;
        margin: 2px;
        padding: 2px;
      }
      
      .Collection {
        border-color: red;
        display: flex;
        flex-direction: column;
      }
      .add {
        border-color: #222;
        cursor: pointer;
        color: #eee;
        background-color: #888;
        text-align: center;
        order: 1;
      }
      <script src='http://code.jquery.com/jquery.js'></script>
      <script src='http://underscorejs.org/underscore.js'></script>
      <script src='http://backbonejs.org/backbone.js'></script>
      <script src='https://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/2.4.3/backbone.marionette.js'></script>

      更新

      在一个更新的示例中,我们扩展 CollectionView 以在渲染时添加我们的自定义元素,并覆盖内部 _insertAfter 方法以在我们的元素之前添加新元素,而不是将其附加到容器的末尾。

      var CollectionView = Mn.CollectionView.extend({
        _insertAfter: function(childView){
          this.$add.before( childView.el );
        },
        onRender: function(){
          this.$add = $('<div class="add">+</div>').click(function(){
            col.add({ title: 'Coffee #'+(++col.counter) });
          }).appendTo( this.el );
        }
      });
      
      var ItemView = Mn.ItemView.extend({
        template: _.template('<%=title%> (<a href="#">remove</a>)'),
        events: { 'click a': 'rm' },
        rm: function(evt){
          this.model.collection.remove( this.model );
        }
      });
      
      var col = new Backbone.Collection([
        {title: 'Espresso'},
        {title: 'Cappuccino'},
        {title: 'Caffe Latte'}
      ]);
      col.counter = 0;
      
      var colview = new CollectionView({
        collection: col,
        className: 'Collection',
        childView: ItemView
      });
      
      colview.render().$el.appendTo(document.body);
      
      col.add({title:'Americano'});
      col.remove( col.at(1) );
      div {
        border: 1px solid gray;
        margin: 2px;
        padding: 2px;
      }
      
      .Collection {
        border-color: red;
      }
      .add {
        border-color: #222;
        cursor: pointer;
        color: #eee;
        background-color: #888;
        text-align: center;
      }
      <script src='http://code.jquery.com/jquery.js'></script>
      <script src='http://underscorejs.org/underscore.js'></script>
      <script src='http://backbonejs.org/backbone.js'></script>
      <script src='https://cdnjs.cloudflare.com/ajax/libs/backbone.marionette/2.4.3/backbone.marionette.js'></script>

      【讨论】:

      • 谢谢 - 几个问题:出于兼容性原因,我不能使用 flexbox,我需要元素浮动,所以 + 必须在容器中,但这为我指明了正确的方向。此外,我们正在寻找具有 Marionette 经验的强大 javascript 开发人员。您是否正在寻找工作?
      • Flexbox 只是一个示例样式,但如果您确实需要将自定义元素保留为最后一个兄弟元素,则还必须覆盖 attachHtml 方法。我会看看是否可以为此添加另一个示例。您也可以通过yuraji at gmail与我联系。
      • 添加了第二个不使用样式进行定位的示例 - 我们的自定义元素始终是集合子视图的最后一个兄弟。
      猜你喜欢
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-10
      • 1970-01-01
      相关资源
      最近更新 更多