For the past few months I've been picking up Backbone, then Marionette.
I quickly liked and later cursed the fact that Backbone gives you some structure yet lots of flexibility, especially around managing views.
At the start the flexibility makes picking things up conceptually easy. As you move beyond the most basic app you need to keep the creation and destruction of views under control, especially when you start nesting them. Backbone gives you very little to handle this, but Marionette plugs the gap nicely.
Terms used in Marionette
- A layout is a type of view that can hold other views
- The element within that layout that holds / wraps the nested view, is called a region. A region can hold one view at a time. It can reload the same view multiple times as required, or swap in different types of view.
- Marionette.Layout actually extends Backbone.View (not directly, but it does inherit from it). So as a layout is a type of view, you can actually nest a layout inside a region of another layout
Your template for the outer layout might be:
.. and your template for the view to be nested inside the region:
Why? I think the view should control its container element, it's more maintainable. You know that everything relating to that view is in one place in your codebase and there are no fragments of the view contained in other templates.
The outer layout can use its regions to show views, when it has been rendered itself. Use the 'show' method of the layout's region. When you call 'show' it automatically calls the render method on the subview.
The View definition for the nested view would contain a className attribute so the view container will be created dynamically when the view is rendered.
You can hook into the onRender and onShow events.
What's the difference between onRender and onShow?
Remember that when the parent region's 'show' method is called, it automatically calls render on the subview as well, so onRender will of course be triggered after that. At this point the view has been templated and a DOM fragment created. However it hasn't yet been attached to the parent region so it's still only in memory and not actually part of the page yet. If you put a breakpoint in the onRender and in your browser console looked for a parent of this.$el (the view's container element):
it would return 0.
The onShow event fires after the view has been attached to its parent region. If you ran the same line in your console during the onShow event, it would return 1.
More reading on Layouts
Marionette provides structure in the biggest areas left vacant by Backbone. One of the best things about it is its creator Derick Bailey is a prolific blogger and documenter (and Stackoverflow lifesaver).
Check out his blog post - Managing Layouts and Nested Views with Backbone.Marionette and the Marionette docs on Layout.