To help visualize the difference (and similarity) of layouts, regions, composites, collections, and item views, I’ve created helpful diagrams to visually demonstrate how the pieces of the puzzle fit together.
Useful when you need to nest multiple views inside of a container and occasionally need to swap them out with other views or show/hide them.
Layouts are the top-level component in your application. You add regions into areas of the application that you plan on turning into Marionette.js views. Areas that don’t need views that are static, such as the header in the example below, should not be assigned a region.
What can go inside a region? Any of the views can go inside, including another layout. You can keep recursing until you run out of memory! (N.B. users do not like it when you consume all of their memory)
A note about swapping views around, the Marionette.js philosophy about re-using views is that you should not re-use them when calling myLayout.region.show(view). Doing so will cause the event binding to get messed up since it does not call delegateEvents within the show() method.
Using our previous example of the word processor application, the layout would be created with the two regions. When the time comes that you want to populate the region, you would execute code like the following. The next section goes into details about the different views that can be put into a region.
I skipped directly to the item view because it’s the simplest of the three Marionette.js views that go inside a region. An item view is Marionette’s tool for providing a view of a single model. Taking a model and a template, the item view will take the values from the model and pass them into the template to populate it.
If we are creating a form for editing a user’s profile, the diagram below is about what it would look like using Marionette.js.
Item views take care of rendering a single model, but now you want to render a collection of models. Marionette.js gives you the CollectionView to help with that. A collection view will render each model and concatenate the HTML together. It does some handy things like automatically handling the rendering when a model is added, removed, or updated in the collection, or if the collection itself is reset.
That’s it, all you do is point it to an item view and initialize it with a collection and it will render all the models. In the example below, we want to render a gallery (collection) of images (model). By creating the collection view with the item view set to the item view of the individual image and then initializing the collection view with a collection of images, we are able to render the entire gallery, using only a few lines of code.
Composite Views (as a wrapper)
In the collection view, you can’t wrap the concatenated HTML with a template. Often times, you’ll want to do this. A simple example would be a table; you can’t just concatenate a bunch of <tr> tags together and plop them onto the page.
That’s where the composite view comes into play. It behaves almost the exact same way as collection view (it actually extends the collection view class), but adds in a template and itemViewContainer option.
This is commonly used when you need to render a collection as an HTML table. Rendering just a collection view containing item views with a top-level container of <tr> would result in a bunch of <tr> tags concatenated together. Using the composite view, you can create a template for the collection, assign the container where all the concatenated item views are inserted, and you’re golden.
Composite Views (as a branch/leaf)
Another, more complicated, use case of a composite view is a that you want to recursively display a collection of models which, themselves, have a collection of models. A common example of this is writing a tree view for a filesystem browser.
I haven’t run into this situation yet, but there is a good blog post that explains the filesystem tree view example.
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.