Иерархия шаблонов Meteor и логика маршрутизации конфликтуют

Мое приложение состоит из двух страниц: домашней страницы и панели инструментов. На главной странице я хочу показать «Вход» (верхняя навигация) и «Регистрация» (основная часть). Если пользователь вошел в систему, покажите панель инструментов. На панели инструментов я хочу показать вариант выхода из системы. При выходе показать домашнюю страницу.

Проблема. Когда я пытаюсь обновить шаблон панели мониторинга, весь контент попадает прямо на панель навигации. Что не менее сбивает с толку, так это то, что основное содержимое страницы домашней страницы все еще отображается на странице панели инструментов. Я явно что-то упускаю из виду, но я не могу сказать, ошибка ли это в моем коде или в моем понимании шаблонов и маршрутов.

Используются: 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: {} */});
  }
});

person Shawn    schedule 06.03.2015    source источник


Ответы (2)


Есть довольно много проблем с тем, как вы определяете свои контроллеры маршрутов, но с этим проблем нет. Я столкнулся с такой же путаницей в том, как правильно их настроить, когда впервые начал использовать Iron-Router, но, надеюсь, после того, как я предложу свои предложения, все станет для вас намного яснее, как и для меня после того, как я немного поработал с Iron-Router. .

Прежде всего, поскольку кажется, что вы собираетесь использовать только один шаблон макета с именем MasterLayout, я бы посоветовал вам определить шаблон макета для вашего приложения на глобальном уровне следующим образом:

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

Это гарантирует, что шаблон MasterLayout используется для всех маршрутов, а шаблон, определенный для любого маршрута, на котором в данный момент находится пользователь, будет отображаться в регионе yield этого шаблона. Что касается того, как правильно построить шаблон MasterLayout, поскольку вы используете конструкцию Bootstrap navbar, я бы предложил структурировать ваш шаблон 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 можно найти здесь.

person Keith Dawson    schedule 13.03.2015
comment
Спасибо, очень полезно! - person Shawn; 18.03.2015

  1. В вашем DashboardController измените layoutTemplate: 'Dashboard', на layoutTemplate: 'MasterLayout',.

  2. {{> Dashboard}} отобразит там шаблон Dashboard. Затем, когда вы вызываете this.render('Dashboard'), вместо {{> yield}} также отображается шаблон панели мониторинга. Вы говорите ему отображать один и тот же шаблон в 2 местах. Итак, в вашем DashboardController измените this.render('Dashboard', { /* data: {} */}); на this.render('Homepage', { /* data: {} */});.

person pstuart2    schedule 06.03.2015