2

我的应用由两个页面组成,主页和仪表板。在主页上,我想显示登录(顶部导航)和注册(主体)。如果用户已登录,则显示仪表板。在仪表板上,我想显示注销选项。注销时显示主页。

问题:当我尝试更新仪表板模板时,所有内容最终都直接进入导航栏。同样令人困惑的是,主页页面的正文内容仍在仪表板页面中呈现。我显然忽略了一些东西,但我不知道这是我的代码中的错误还是我对模板和路由的理解中的错误。

使用中:Iron-Router、Accounts-UI 和 Accounts-password、Twbs:bootstrap。

下面插入的是三个主要模板 Master、Homepage 和 Dashboard。

提前感谢您提供的任何帮助!

带有如果登录逻辑的主模板

<template name="MasterLayout">
    {{> yield}}
    <nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">THE BRAND</a>
      </div>
      <div id="navbar" class="navbar-collapse collapse">
        {{#if currentUser}}
          {{> Dashboard}}
        {{else}}
          {{> Login}}
        {{/if}}
      </div><!--/.navbar-collapse -->
    </div>
  </nav>
</template>

主页包含主要内容

<template name="Homepage">
  <div class="jumbotron">
    <div class="container">
      <h1>Get it now..</h1>
      <p>Donec id elit</p>
      {{#if currentUser}}
        hello
      {{else}}
        {{> Register}}
      {{/if}}
    </div>
  </div>
</template>

仪表板包含占位符文本

<template name="Dashboard">
  <ul class="nav navbar-nav">
    <li class="navbar-text">Navigation Placeholder</li>
    <li><a href="#" class="logout">Logout</a></li>
  </ul>
</template>

我创建了以下控制器;

主页

HomepageController = RouteController.extend({
  layoutTemplate: 'MasterLayout',

  subscriptions: function() {
  },

  action: function() {
    this.render('Homepage');
  }
});

仪表板

DashboardController = RouteController.extend({
  layoutTemplate: 'Dashboard',

  subscriptions: function () {
  },

  data: function () {
  },

  action: function () {
    this.render('Dashboard', { /* data: {} */});
  }
});
4

2 回答 2

2

定义路由控制器的方式有很多问题,但没问题。当我第一次开始使用 Iron-Router 时,我对如何正确设置它们也有同样的困惑,但希望在我提供我的建议之后,事情对你来说会变得更加清晰,就像在我使用 Iron-Router 一段时间后他们对我所做的那样.

首先,由于您似乎只打算使用一个名为 的布局模板MasterLayout,我建议您在全局级别为您的应用程序定义布局模板,如下所示:

    Router.configure({
        layoutTemplate: 'MasterLayout'
    });

这确保MasterLayout模板用于所有路由,并且为用户当前所在的任何路由定义的模板将在该模板的yield区域中呈现。至于如何正确构造MasterLayout模板,由于您使用的是 Bootstrapnavbar构造,我建议您MasterLayout像这样构造模板:

    <template name="MasterLayout">
        <header>
            <nav class="navbar navbar-inverse navbar-fixed-top">
                <div class="container">
                    <div class="navbar-header">
                        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                            <span class="sr-only">Toggle navigation</span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                        </button>
                        <a class="navbar-brand" href="#">THE BRAND</a>
                    </div>
                    <div id="navbar" class="navbar-collapse collapse">
                        {{> loginButtons align="right"}}
                    </div>
                </div>
            </nav>
        </header>
        <article>
            {{> yield}}
        </article>
    </template>

我建议将整个navbar构造放入一个<header>元素中,而将yield布局模板的区域放入一个article元素中。确实,您可以将这两个不同的部分放入您想要的任何类型的标签中,但我建议这样做,以便正确利用 HTML5 标签并适当地分隔页面。

如前所述,yield区域是插入当前路由模板的位置。此外,为了使用登录/注销按钮实现您的目标,只需将{{> loginButtons}}模板(由 Accounts-UI 包提供)引用也放入navbar构造中。它将对当前用户是否登录或注销做出反应,并相应地显示带有文本的适当按钮。如果您希望像我喜欢的那样将登录按钮对齐到结构的右侧navbar,您可以将navbar-right类添加到<ul>元素以及将align="right"属性添加到{{> loginButtons}}模板参考。这确保了当按钮被拉到页面的右边缘时,登录按钮将在按钮的左侧和页面上打开,而不是在页面的右侧和关闭。

为了实现您在上面指定的行为,我进一步建议定义两条路由,一条用于主页,一条用于仪表板,如下所示:

    Router.route('/', {
        name: 'Homepage',
        template: 'Homepage'
    });

    Router.route('/dashboard', {
        name: 'Dashboard',
        template: 'Dashboard'
    });

定义这些路由后,您可以定义它们在template选项中引用的两个模板(以及可能的子模板),如下所示:

    <template name="Homepage">
        ...
        {{> Register}}
        ...
    </template>

    <template name="Dashboard">
        ...
    </template>

    <template name="Register">
        ...
    </template>

老实说,在这种情况下,您实际上不需要定义Register模板,因为它已经在单独的Homepage模板中定义了,并且您考虑放入模板中的任何内容都Register可以直接放入Homepage模板中并保存复杂性。这两个路由及其关联模板将提供您在上面指定的两个不同页面。

完成这项工作后,剩下要做的就是创建适当的 Javascript,如下所示:

    Router.onBeforeAction(function() {
        if(!Meteor.user()) {
            this.redirect('Homepage');
        }  else {
            this.next();
        }
    });

    if(Meteor.isServer) {
        Accounts.onLogin({
            Router.go('Dashboard');
        });
    }

如果用户注销,代码的第一部分将用户重定向到Homepage路由,而代码的第二部分在用户Dashboard登录时将用户重定向到路由。

实际上,您真的不需要像上面那样使用路由控制器。由于您只有两条路线,因此您只需像我一样定义两条路线并根据需要添加适当的选项即可轻松摆脱困境。

万一您还没有找到它,可以在这里找到 Iron-Router 的一个很好的参考。

于 2015-03-13T20:38:26.423 回答
1
  1. 在您的 DashboardController 中更改layoutTemplate: 'Dashboard',layoutTemplate: 'MasterLayout',.

  2. {{> Dashboard}}将在那里呈现仪表板模板。然后,当您调用this.render('Dashboard')它时,它还将呈现 Dashboard 模板代替{{> yield}}. 您告诉它在 2 个地方呈现相同的模板。因此,在您的 DashboardController 中更改this.render('Dashboard', { /* data: {} */});this.render('Homepage', { /* data: {} */});.

于 2015-03-06T03:43:58.723 回答