【问题标题】:Backbone.Marionette: Add header to collection viewBackbone.Marionette:将标题添加到集合视图
【发布时间】:2013-08-01 03:15:06
【问题描述】:

使用Backbone.Marionette,我想渲染一组项目以及一个标题。

我知道Marionette.CollectionView 没有模板,因为它只呈现ItemViews。

我目前正在使用Marionette.LayoutView,但必须为“列表”区域定义一个额外的 DOM 元素。

还有其他方法可以做到这一点吗?可能没有额外的 DOM 元素?

也许我可以为这个特定区域更改open()


当前结果

<div class='collection'>
  <h3>Featured</h3>
  <div class="list"></div>
</div>

期望的结果

<div class='collection'>
  <h3>List Name</h3>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
    <li>Item 3</li>
   </ul>
</div>

渲染代码

var col = new LCollection([{name: "foo"}, {name: "bar"}]); // Defined earlier, not relevant here
var list = new ListView({collection: col});
var layout = new MyLayout({model: new Backbone.Model({name: "Featured"})});

app.featured.show(layout);
layout.list.show(list);

观看次数

var ListItemView = Backbone.Marionette.ItemView.extend({
  template: '#list-item',
  tagName: 'li'
});

var LessonListView = Backbone.Marionette.CollectionView.extend({
  tagName: 'ul',
  itemView: ListItemView
});

var MyLayout = Backbone.Marionette.Layout.extend({
  template: "list-layout",

  regions: {
    list: '.list'
  }
});

模板

<script type="text/template" id="list-item">
  <%= name %>
</script>

<script type="text/template" id="list-layout">
  <h3><%= name %></h3>
  <div class="list"></div>
</script>

【问题讨论】:

标签: javascript backbone.js marionette


【解决方案1】:

https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.compositeview.md

为你申请:

模板

<script id="list-item" type="text/html">
  <%= name %>
</script>

<script id="list-layout" type="text/html">
    <div class='collection'>
        <h3><%= name %></h3>
        <ul></ul>
    </div>
</script>

JS

RowView = Backbone.Marionette.ItemView.extend({
  tagName: "li",
  template: "#list-item"
});

TableView = Backbone.Marionette.CompositeView.extend({
  itemView: RowView,
  // specify a jQuery selector to put the itemView instances in to
  itemViewContainer: "ul",
  template: "#list-layout"
});

【讨论】:

  • 不敢相信我以前没有看到这个:or for scenarios where a collection needs to be rendered within a wrapper template. 我会试试这个,如果它有效,会告诉你。谢谢!
  • 现在是“childView”和“childViewContainer”而不是“itemView”和“itemViewContainer”
  • @CraigMyles 我希望我早点注意到你的评论 - 这样可以节省我一个小时左右:)
  • @MikhailBatcer 我不知道现在应该说什么。在那里进行编辑以使其保持最新
【解决方案2】:

Marionette 3 不再使用CompositeView,所以如果我们想得到这样的东西:

<div class='collection'>
  <h3>List Name</h3>
  <ul>
    <li>FOO - BAR</li>
    <li>FOO - BAR</li>
    <li>FOO - BAR</li>
    ...
 </ul>
</div>

我们必须在区域中使用CollectionViewView

1 - 模板

我们将定义两个模板,第一个是“父母”,另一个是父母拥有的每个“孩子”。

parentTemplate.html

<div class='collection'>
    <h3>List Name</h3>
    <ul></ul>
</div>

childTemplate.html

<p>Item <%= value%></p>

2 - 骨干模型和集合

让我们定义一个默认模型及其集合来填充列表。

const Item = Backbone.Model.extend({});
const Items = Backbone.Collection.extend({
    model: Item
});

3 - 观看次数

首先,我们必须为我们的子表示创建一个View,所以:

import ItemViewTemplate from './childTemplate.html';    

const ItemChildView = Marionette.View.extend({
    template: _.template(ItemViewTemplate),
    className: 'item-child-view',
    tagName: 'li' // <-- The element where we will wrap our item template (it is not defined in the HTML file)
});

其次,我们必须创建一个管理每个孩子的CollectionView,所以:

const ItemsCollectionView = Marionette.CollectionView.extend({
    tagName: 'ul', // <-- The element where we will wrap our collection of items (it is already in the parent HTML file)
    childView: ItemChildView,
    className: 'items-collection-view'
});

最后,我们必须创建包含 parentTemplate.html 的主 View,并在其中定义我们将加载元素集合的区域,因此:

import ItemsViewTemplate './parentTemplate.html';    

const ItemsView = Marionette.View.extend({
    tagName: 'div',
    className: 'items-view',
    template: _.template(ItemsViewTemplate),
    regions: {
        body: {
            el: 'ul', // <-- This is the HTML tag where we want to load our CollectionView
            replaceElement: true // <-- With this option, we overwrite the HTML tag with our CollectionView tag
        }
    }
});

4- 其余代码

现在我们创建实现此功能所需的实例:

const app = new Marionette.Application({
    region: '#main'
});

// Three simple Items
let item1 = new Item({value: 1});
let item2 = new Item({value: 2});
let item3 = new Item({value: 3});

// Put this Items into a Collection of Items
let items = new Items([item1, item2, item3]);

// Create the main View
let itemsView = new ItemsView();

app.showView(itemsView);

// Create the CollectionView for the Items
let itemsCollectionView = new ItemsCollectionView({
    collection: items
});

// Load the CollectionView of Items into the region that we specified in the main View
itemsView.showChildView('body', itemsCollectionView);

app.start();

5- 结果

如果我们运行它,我们会得到:

<div class="collection">
    <h3>List Name</h3>
    <ul class="items-collection-view">
        <li class="item-child-view"><p>Item1</p></li>
        <li class="item-child-view"><p>Item2</p></li>
        <li class="item-child-view"><p>Item3</p></li>
    </ul>
</div>

希望对您有所帮助! Reference

【讨论】:

    【解决方案3】:

    我相信上面的解决方案会直接在包含的 div 或指定的其他区域下渲染 li 元素,除非你也指定

    tagName: "ul"
    

    然后在指定区域内渲染一个ul元素内的li元素。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多