In part one we looked at how to attach a Marionette view to the existing HTML for a navigation bar. There, we didn't need to replace the HTML; we just needed to augment it to handle click events.
This post will consider the case where we want to be able to replace the existing HTML at a later point in time. This blog page itself is an example use case: the blog is a small Marionette application, and it's View class attaches to the existing server-rendered content on startup. If you clicked a link to another blog page, another View class would take over and replace the server-rendered text with text for the new page.
I've extended the runnable example on github to illustrate this, too. That example has pre-rendered content and two separate views, and the first view just attaches to the pre-rendered content instead of creating its own.
In the last post, we saw how to attach a view to existing HTML, and we'll do the same thing here. But we also need to switch between views, and that's where Marionette's Region comes in.
A special use of Marionette.Region
Marionette's Region takes care of cleanly switching between views. We can set one up normally when the client Application instance starts:
We're calling Application's
addRegion to attach a Region to the right spot in the HTML, which in our case is specified via the selector
#primary-region. This call just attaches the new Region to the existing HTML without replacing any existing content there.
Normally, we display a view in a region by calling the region's
show function, which renders the view and displays it within the region's
div. But we can't do that here -- that would replace the pre-rendered HTML, which we want to preserve until the user navigates off of the first page.
Luckily, Marionette's Region has a special function just for this situation:
attachView. This puts the view under the region's control, without rendering the view or changing the pre-rendered content at all. Here's how we create the view and attach it to the region via
This takes care of the first-view situation, but it will prevent that same view from rendering properly if the user navigates to another page & then back to this one within the same application.
Distinguishing between first-view & subsequent views
We'll add some logic to the Controller so we can handle this special-case creation logic on first view, and then creating all later views in the normal way:
We added the flag variable
isFirstView to keep track of the special case of first-view. If it is the first view, we create the view so it uses the pre-rendered content, and then call the region's
attachView instead of
show to preserve that content. For later uses of the view, we just create the view normally and
show it in the region. This allows the region to clean up the old view and its content.
In the runnable example I put together on github, you can see this code in the files
I've found this approach to be useful not only for this blog's client application, but also for any Marionette application that gets pre-rendered content from the server. The result is a great combination of a quick first-view load with all of the nice View and Region benefits we get from Marionette.