3
votes

Essentially I have an app Layout with a common header and footer section for a particular route. The thing is I want to be able to transition the main content region for this layout when a sub-route has been hit.

Example: #products being the main route and #products/:id being the sub route.

In my controller for this module I am using require.js to grab the view for the #products route and show the landing with the global header and footer as part of this layout's regions. I am also defining a content region, which is the one I want to transition out once an id is included in the route. So how can I call methods on the view once this new route has been hit? Would I need to cache the current state of the application when the parent route is hit and then reference this when the sub-route is hit? And would I also need to init the view when the sub-route is hit and the parent route has not been visited by the user?

Router

define(['backbone', 'marionette', 'c_controllers/Controller'], function ( Backbone,          Marionette, Controller ) {

'use strict';

var AppRouter = Backbone.Marionette.AppRouter.extend({

    appRoutes : {
        // PRODUCT ROUTES
        'product' : 'product',
        'product/:id' : 'showPlp'
    }
});

return new AppRouter({'controller': Controller});

});

Controller

define(["backbone", 'marionette'], function (Backbone, Marionette) {

    'use strict';

    return {

        product : function( id ) {

            require(['c_product/product', 
                    'app_views/menu'], function( Product, Menu ) {

                APP.menu.show( new Menu() );
                APP.page.show( new Product() );
            });
        }       
   };
});

View

define([
'backbone', 'marionette', 'app_views/globalNav', 
'c_product/productLanding', 'text!productNavTemplate', 'text!productBaseTemplate'], function( Backbone, Marionette, GlobalNav, ProductLanding, ProductNavTemplate, ProductBaseTemplate ) {

var product = Backbone.Marionette.Layout.extend({

    id : 'product',
    template : _.template( ProductBaseTemplate ),
    regions : {

        nav : '#globalNav',
        content : '#view-content',
        footer : '#footer'
    },

    events : {

    },

    initialize : function() {

    },

    onRender : function() {

        // extend the nav view for the template that matches this flow
        var Nav = GlobalNav.extend({ template : _.template( ProductNavTemplate )});

        // show the nav, main content, and footer
        this.nav.show( new Nav() );
        this.content.show( new ProductLanding() );
    }
});

return product;
});
1

1 Answers

1
votes

I had exactly the same question when designing my latest Marionette Code Base. I wanted to make a Single Page App that behaved like a web site and would allow for proper canonocical paths.

My solution was as follows:

Have a single Marionette Layout that rendered the base site page, i.e. the Headers, Footers and a blank content region.

Have my router send messages to my main site layout telling it what content view to render.

I used Backbone.Wrqr commands to send messages between the Router and the Main Site Layout.

Implement a click handler in the browser to capture clicks on internal site links and direct then to the Marionette router.

There is quite of lot of code involved to demonstrate it so I have put a full write up on my own site, the site is also a working example of this technique.

The full Article is Changing A Layouts Region Based On A Sub Route Using Backbone And Marionette