I have a collection rendering well using Backbone/Marionette/Mustache.
So PersonModel
and PersonView
are working fine. PersonView
has a mustache template called PersonTemplate
that is being loaded perfectly by my PeopleCollection
and PeopleCollectionView
and rendering inside a default tagname: "div"
.
However, I want to render this collection inside of another template so I can put some headers there.
Right now it's essentially:
<div> <!-- collection tagName -->
<div class="person"> <!-- PersonTemplate -->
<div class="person-name">John</div>
</div>
<div class ="person"> <!-- PersonTemplate -->
<div class="person-name">Dave</div>
</div>
</div>
But I would like it to be:
<div id="people> <!-- CollectionTemplate -->
<h1>People</h1> <!-- CollectionTemplate -->
<div class="person"> <!-- PersonTemplate -->
<div class="person-name">John</div>
</div>
<div class ="person"> <!-- PersonTemplate -->
<div class="person-name">Dave</div>
</div>
</div>
I understand I can add these items with jQuery after the fact, but I was hoping to avoid that because my actual CollectionTemplate
is much more complex than the example given here.
CompositeView is exactly what you need. Here is how I have CompositeView setup for simple notes panel.
Item View for each note:
View.NoteRow = Marionette.ItemView.extend({
template: Handlebars.compile(rowTemplate),
tagName: "tr",
className: "row-item",
})
The Composite View:
View.NotesPanel = Marionette.CompositeView.extend({
template: Handlebars.compile(panelTemplate),
itemView: View.NoteRow,
itemViewContainer: "tbody",
className: "panel panel-default button-panel notes-panel",
events: {
"click button#add-note" : "addNote"
}
})
Now the templates:
panelTemplate:
<div class="panel-heading">
<div class="container-fluid">
<div class="row ">
<div class="col-md-6 col-lg-9">
<h3 class="panel-title"><i class="fa fa-pencil"></i> Notes</h3>
</div>
<div class="col-md-6 col-lg-3 button-column">
<a href="#"><button id="add-note" class="btn btn-xs btn-success"><i class="fa fa-plus"></i> Add Note</button></a>
</div>
</div>
</div>
</div>
<div class="panel-body">
<table id="notes-table" class="table">
<thead>
<tr>
<th>User</th>
<th>Note</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
And the row template:
<td>{{employee_id}}</td>
<td>
<p>{{note_text}}</p>
<p><span class="tooltip-span timestamp" id="account-created" data-toggle="tooltip" title="{{created_at}}">{{humanize created_at}}</span></p>
</td>
In your CompositeView definition you specifiy what template you want to use (panelTemplate) in my example. Than you specify which ItemView to use for each model in the collection that composite view holds. (View.NoteRow in my example). Than you define the container within your template that each ItemView will go into ( I'm each of my ItemViews into )