在 Marionette CollectionView 中显示不是集合成员的项目?

Display item in Marionette CollectionView that's not member of the collection?

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

X X X X
X X X 

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

X X X X
X X X +

有没有人知道如何使用 Marionette 完成此操作?

虽然您可以手动添加 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>

我们在我们的应用程序中就是这么做的。为了实现它,我们有一个带有模板的复合视图:

<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-buttondiv也浮动,你就会得到你想要的。

http://jsfiddle.net/cn1gp4m4/