Search code examples
javascriptmeteoriron-router

Inheriting yield templates from super controller with iron-router


I have a super controller: ApplicationController which yields to my regions: header/footer. When one of my configured routes attempts to yield to another region on another template, the parent controller's yieldTemplates are overridden.

Example:

   ApplicationController = RouteController.extend({
    yieldTemplates: {
        'footer': { to: 'footer' },
        'header': {to: 'header'}
    }
});

var SignUpController = ApplicationController.extend({
    template: 'signUp'

});

Router.map(function () {


    this.route('signup', {
        path: '/sign-up',
        controller: SignUpController,
        template: 'signUp-form',
        disableProgress: true,
        yieldTemplates: {
            'personal-signup': {to: 'signup-detail'}
        }
    });
});

Any idea why inheritance isn't working in this situation ?


Solution

  • I had a similar issue, read the answer here: https://github.com/EventedMind/iron-router/issues/249#issuecomment-27177558

    What's happening is your Router level config is overriding the RouteController prototype. In general, options override prototype properties in iron-router.

    A simple solution is to create a global object with the main yields, and then extend that object on each Controller when new yields are necessary:

    var mainYieldTemplates = {
        'footer': { to: 'footer' },
        'header': {to: 'header'}
    };
    
    ApplicationController = RouteController.extend({
        yieldTemplates: mainYieldTemplates
    });
    
    var SignUpController = ApplicationController.extend({
        template: 'signUp',
        yieldTemplates: _.extend({}, mainYieldTemplates, {
                'personal-signup': {to: 'signup-detail'}
            }
        )
    });
    
    Router.map(function () {
        this.route('signup', {
            path: '/sign-up',
            controller: SignUpController,
            template: 'signUp-form',
            disableProgress: true,
        });
    });
    

    There is also a minor inconsistency in your code where you declare the "template" property to be "signUp" in the controller, but then in the route itself you set it to "signUp-form". This will overwrite the "template" property on the controller. You can instead create a new controller for each route with all of the route's properties instead of overwriting them.