Marionette.CompositeView
DEPRECATED: CompositeView
is deprecated. See CollectionView to see how to build equivalent views in Marionette 3
A CompositeView
extends from CollectionView
to be used as a composite view for scenarios where it should represent both a branch and leaf in a tree structure, or for scenarios where a collection needs to be rendered within a wrapper template. By default the CompositeView
will maintain a sorted collection's order in the DOM. This behavior can be disabled by specifying {sort: false}
on initialize.
Please see the Marionette.CollectionView documentation for more information on available features and functionality.
Example Usage: Tree View
For example, if you're rendering a tree-view control, you may want to render a collection view with a model and template so that it will show a parent child with children in the tree.
var CompositeView = Marionette.CompositeView.extend({
template: "#leaf-branch-template"
});
new CompositeView({
model: someModel,
collection: someCollection
});
Documentation Index
- Composite Model
template
- CompositeView's
childView
- CompositeView's
childViewContainer
- CompositeView's
attachHtml
- CompositeView's
renderChildren
- Recursive By Default
- Model And Collection Rendering
- Events And Callbacks
- Organizing UI elements
- modelEvents and collectionEvents
Composite Model template
When a CompositeView
is rendered, the model
will be rendered with the template
that the view is configured with. You can override the template by passing it in as a constructor option:
new MyComp({
template: "#some-template"
});
The collection
option is not passed to the template context by default. If your template
needs access to the collection, you'll need to pass it via templateContext
:
new MyComp({
template: "#some-template",
templateContext: function() {
return { items: this.collection.toJSON() };
}
})
CompositeView's childView
Each childView will be rendered using the childView
's template. The CompositeView
's template is rendered and the childView's templates are added to this.
var ChildView = Marionette.View.extend({});
var CompView = Marionette.CompositeView.extend({
childView: ChildView
});
You can also define childView
as a function, which allows you to choose the view class to be rendered at runtime.
For more information see the CollectionView's documentation.
CompositeView's childViewContainer
By default the composite view uses the same attachHtml
method that the collection view provides. This means the view will call jQuery's .append
to move the HTML contents from the child view instance in to the collection view's el
.
This is typically not very useful as a composite view will usually render a container DOM element in which the child views should be placed.
For example, if you are building a table view, and want to append each child from the collection in to the <tbody>
of the table, you might do this with a template:
<script id="row-template" type="text/html">
<td><%= someData %></td>
<td><%= moreData %></td>
<td><%= stuff %></td>
</script>
<script id="table-template" type="text/html"></script>
To get your childView instances to render within the <tbody>
of this table structure, specify an childViewContainer
in your composite view, like this:
var RowView = Marionette.View.extend({
tagName: "tr",
template: "#row-template"
});
var TableView = Marionette.CompositeView.extend({
childView: RowView,
// specify a jQuery selector to put the `childView` instances into
childViewContainer: "tbody",
template: "#table-template"
});
This will put all of the childView
instances into the <tbody>
tag of the composite view's rendered template, correctly producing the table structure.
Alternatively, you can specify a function as the childViewContainer
. This function needs to return a jQuery selector string, or a jQuery selector object.
var TableView = Marionette.CompositeView.extend({
// ...
childViewContainer: function(){
return "#my-tbody"
}
});
Using a function allows for logic to be used for the selector. However, only one value can be returned. Upon returning the first value, it will be cached and that value will be used for the remainder of that view instance' lifecycle.
Alternatively, the childViewContainer
can be supplied in the constructor function options:
var myComp = new Marionette.CompositeView({
// ...,
childViewContainer: "#my-tbody"
});
CompositeView's attachHtml
Sometimes the childViewContainer
configuration is insufficient for specifying where the childView
instance should be placed. If this is the case, you can override the attachHtml
method with your own implementation.
For more information on this method, see the CollectionView's documentation.
CompositeView's childView
container selection
The getChildViewContainer
method is passed a second childView
parameter which, when overridden, allows for a finer tuned container selection by being able to access the childView
which is about to be appended to the containerView
returned by getChildViewContainer
.
CompositeView's renderChildren
The renderChildren
method re-renders the views within the childViewContainer
for the collection without re-rendering the surrouding template.
Recursive By Default
The default rendering mode for a CompositeView
assumes a hierarchical, recursive structure. If you configure a composite view without specifying an childView
, you'll get the same composite view class rendered for each child in the collection.
Model And Collection Rendering
The model and collection for the composite view will re-render themselves under the following conditions:
- When the collection's "reset" event is fired, it will only re-render the collection within the composite, and not the wrapper template
- When the collection has a model added to it (the "add" event is fired), it will render that one child into the list
- When the collection has a model removed (the "remove" event is fired), it will remove that one child from the rendered list
As with item view instances, the composite view instance is passed as the third argument to the Renderer
object's render
method, which is useful in custom Renderer
implementations.
Events And Callbacks
During the course of rendering a composite, several events will be triggered. These events are triggered with the Marionette.triggerMethod function, which calls a corresponding "on{EventName}" method on the view.
- "before:render:children" /
onBeforeRenderChildren
- before the collection of models is rendered - "render:children" /
onRenderChildren
- after the collection of models has been rendered - "before:render" /
onBeforeRender
- before anything has been rendered - "render" /
onRender
- after everything has been rendered
Additionally, after the composite view has been rendered, an onRender
method will be called. You can implement this in your view to provide custom code for dealing with the view's el
after it has been rendered:
Marionette.CompositeView.extend({
onRender: function(){
// do stuff here
}
});
Organizing UI elements
Similar to View, you can organize the UI elements inside the CompositeView by specifying them in the UI
hash. It should be noted that the elements that can be accessed via this hash are the elements that are directly rendered by the composite view template, not those belonging to the collection.
The UI elements will be accessible as soon as the composite view template is rendered (and before the collection is rendered), which means you can even access them in the onBeforeRender
method.
modelEvents and collectionEvents
CompositeViews can bind directly to model events and collection events in a declarative manner:
Marionette.CompositeView.extend({
modelEvents: {
"change": "modelChanged"
},
collectionEvents: {
"add": "modelAdded"
}
});
© 2017 Muted Solutions, LLC
Licensed under the MIT License.
https://marionettejs.com/docs/v3.5.1/marionette.compositeview.html