流星:使用2种不同的布局(铁:路由器)

时间:2015-03-04 21:06:48

标签: javascript meteor

在客户端上,我想呈现两种不同的布局。

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

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

在这种情况下,只有第一个Router.route功能有效。这个代码示例中的问题似乎是什么?

在控制台中,会弹出此错误:

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

此外,如果用户未登录,我也不希望用户访问“主要' -template”。iron:router documentation并未向我提供有关如何使用的足够信息处理这两个问题。

3 个答案:

答案 0 :(得分:4)

这是你的路线应该是这样的。

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

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

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

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

/client/views/layout.html

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

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

答案 1 :(得分:3)

我绝对认为您上面的路由代码存在的问题是您没有为路径template指定路径'/main'属性的值。至少,我建议您定义该属性,如果给定路线没有别的。铁路由器将尝试确定用于路由的模板的第一件事是查看URL的路径,并且对于确定给定路由并不总是显而易见的。我建议像上面那样定义你的路线:

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

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

定义了这个路由逻辑后,您还需要确保正确定义模板。

对于您的布局模板,请执行以下操作:

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

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

布局模板中需要{{> yield}}部分,因为铁路由器将通过template属性呈现您为路径定义的模板。

对于常规模板,请执行以下操作:

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

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

执行此操作后,您的路线是否有效?或者,您可以使用Route.configure设置全局路由属性,或使用一系列RouteController对象来定义路由,以便公共路由可以利用公共属性定义。

至于你的第二个问题,我建议使用以下两种方法之一:

为了仅为'/main'路线定义您描述的逻辑,请执行以下操作:

    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();
            }
        }
    });

使用此选项需要您在'/'路线name: 'register'添加其他属性。或者,您可以在this.render()this.redirect()函数调用中直接引用所需路径的实际URL路径,然后您不必为模板定义name属性。就个人而言,我更喜欢通过给出所有名称并使用他们的名字引用它们来明确和开放我的路线定义。

第二个选项是全局定义所需的逻辑,使其不仅适用于'/main'路由,还适用于您将来碰巧定义的任何其他路由。为此,请执行以下操作:

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

此选项再次要求为name路由定义'/'属性,但如果您不想这样做,则可以执行上述操作。最后,请注意此选项末尾的except属性定义。这通知铁路由器不为指定路由数组运行此全局定义的逻辑。显然,您不希望在重定向当前未登录用户的页面上运行此逻辑,因此我的上面是except属性定义。

答案 2 :(得分:0)

我猜您需要定义'/main'路由的模板 - 这将是您错误中的undefined。如果您的模板具有name="main"属性,我需要查看更多代码,尤其是任何模板处理程序。

可以使用onBeforeAction回调来完成重定向:

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