最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Meteor: use 2 different layouts (iron:router) - Stack Overflow

programmeradmin0浏览0评论

On the client I want to render two different layouts.

Router.route('/',  {
    template: 'register',
    layoutTemplate: 'home'
});

Router.route('/main', {
    layoutTemplate: 'layout'
});

In this case only the first Router.route function works. What seems to be the problem in this code example?

In the console, this error pops up:

Exception in defer callback: TypeError: Cannot read property 'handler' of undefined

Additionally I don't want users to access the 'main'-template if they are not logged in. The iron:router documentation doesn't provide me enough information on how to handle both these issues.

On the client I want to render two different layouts.

Router.route('/',  {
    template: 'register',
    layoutTemplate: 'home'
});

Router.route('/main', {
    layoutTemplate: 'layout'
});

In this case only the first Router.route function works. What seems to be the problem in this code example?

In the console, this error pops up:

Exception in defer callback: TypeError: Cannot read property 'handler' of undefined

Additionally I don't want users to access the 'main'-template if they are not logged in. The iron:router documentation doesn't provide me enough information on how to handle both these issues.

Share Improve this question asked Mar 4, 2015 at 21:06 FullhdpixelFullhdpixel 8231 gold badge13 silver badges28 bronze badges 2
  • See this post for how to prevent users who are not logged in from accessing specific routes. – David Weldon Commented Mar 4, 2015 at 21:20
  • @DavidWeldon thanks. That is some great input. Do you happen to know a workaround or solution for the first issue mentioned? – Fullhdpixel Commented Mar 4, 2015 at 21:26
Add a ment  | 

3 Answers 3

Reset to default 4

This is how your routes should look.

 //Layout Configuration.
    Router.configure({
      layoutTemplate:"register"
    });

    Router.configure({
      layoutTemplate:"layout"
    });

   //Simple Routes Config.
    Router.route('/',  {
        layoutTemplate: 'register'
    });

    Router.route('/main', {
        layoutTemplate: 'layout'
    });

And The /client/views/layout.html

<template name="layout">
  {{> yield}}
</template>

<template name="register">
  {{> yield}}
</template>

I definitely think that the issue with your routing code above is the fact that you have not specified a value for the template attribute of your route with the path '/main'. At the very least, I would suggest that you define that attribute if nothing else for a given route. The first thing that iron-router will attempt to do to determine which template to use for the route is to look at the path of the URL, and that is not always obvious to determine for a given route. I would suggest defining your routes above like so:

    Router.route('/', function() {
        template: 'register',
        layoutTemplate: 'home'
    });

    Router.route('/main', function() {
        template: 'main',
        layoutTemplate: 'layout'
    });

With this routing logic defined, you would then also want to make sure to define your templates properly.

For your layout templates, do something like the following:

    <template name="home">
        {{> yield}}
    </template>

    <template name="layout">
        {{> yield}}
    </template>

The {{> yield}} parts are necessary here in the layout templates because that is where iron-router will render the template that you have defined for the route through the template attribute.

For your regular templates, do something like the following:

    <template name="register">
        <h1>Register</h1>
    </template>

    <template name="main">
        <h1>Main</h1>
    </template>

After doing this, do your routes work? Alternatively, you could use Route.configure to set global route attributes, or a series of RouteController objects to define your routes so that mon routes can take advantage of mon attribute definitions.

As for your second issue, I would suggest using one of the two following methods:

In order to define your described logic for just the '/main' route, do the following:

    Router.route('/main', function() {
        template: 'main',
        layoutTemplate: 'layout',
        onBeforeAction: function() {
            if(!Meteor.userId()) {
                this.render('register'); // Use either this one
                this.redirect('register'); // or this one
            } else {
                this.next();
            }
        }
    });

Going with this option will require that you add an additional attribute to your '/' route, name: 'register'. Alternatively you can directly reference the actual URL path of the desired route in the this.render() or this.redirect() function calls and then you do not have to define the name attribute for your templates. Personally, I prefer being obvious and open with my route definitions by giving them all names and referencing them using their names.

The second option is to define your desired logic globally so that it applies not only to the '/main' route, but to any other routes that you happen to define in the future as well. To do this, do the following:

    Router.onBeforeAction(function() {
        if(!Meteor.userId()) {
            this.render('register'); // Use either this one
            this.redirect('register'); // or this one
        } else {
            this.next();
        }
    },
    {
        except: ['register']
    });

Once again, this option requires the definition of the name attribute for your '/' route, but you can do what I described above if you prefer not to do that. Finally, notice the except attribute definition at the end of this option. This notifies iron-router to not run this globally-defined logic for the array of specified routes. Obviously, you would not want to run this logic on the very page to which you are redirecting users who are not currently logged in, hence my except attribute definition above.

My guess is you need to define the template for the '/main' route as well--that would be what is undefined in your error. If you have a template with the name="main" attribute, I would need to see more code, particularly any template handlers.

A redirect could be acplished with the onBeforeAction callback:

onBeforeAction: function() {
    if (!Meteor.userId()) {
        this.redirect('/');
    } else {
        this.next();
    }
}
发布评论

评论列表(0)

  1. 暂无评论