Отдельные макеты для разных типов пользователей

У меня есть два разных типа пользователей: «читатель» и «издатель». Эта информация хранится в документе Meteor.users Meteor.users.userType: 'publisher' или может Meteor.users.userType:'reader'

Как я могу динамически добавлять элементы в appBody в зависимости от userType?

Контекст данных и такие вещи, как элементы меню, конечно, будут отличаться для пользовательских типов.

Я сослался на https://github.com/EventedMind/iron-dynamic-template

HTML:

<head>
 <title>Site</title>
</head>

<template name="appBody"> //this is layoutTemplate
    <div class="navbar navbar-fixed-top navbar-custom">
        <div class = "container">
            <ul class="nav navbar-nav navbar-right">
                <li><a href="#">menu title A</a></li>
                <li><a href="#">menu title B</a></li>
                ***DYNAMICALLY ADD LIST ELEMENT DEPENDING ON WHICH 'userType' IS LOGGED IN HERE***
            </ul>
        </div>
    </div>
    {{> UI.dynamic template=currentUser.userType }}
</template>


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


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

router.js

Router.configure({
    layoutTemplate: 'appBody',
    loadingTemplate: 'appLoading'
});

person meteorBuzz    schedule 05.12.2014    source источник


Ответы (2)


Если вы хотите продолжать использовать UI.dynamic, я предлагаю написать собственную функцию выбора шаблона:

Перефразируя https://github.com/EventedMind/iron-dynamic-template, нужно выглядеть так:

if (Meteor.isClient) {
  UI.body.helpers({
   getTemplate: function () {
     return something;
   }
  });
}

Я бы предложил переименовать помощника в userType и использовать его следующим образом:

if (Meteor.isClient) {
  UI.body.helpers({
    userType: function () {
     var user = Meteor.user();
     return (user && user.userType)? user.userType : ''; 
   }
  });
}

и используя {{> UI.dynamic template=userType }}

Вы можете изменить '' в операторе return на 'anonymous', если он не работает для пользователей, которые не вошли в систему, но тогда вам также потребуется написать шаблон типа анонимного пользователя.

Однако для этого вам не нужен UI.dynamic:

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

{{#if userTypeIs "publisher"}}
 {{ > publisher }}
{{/if}}
{{#if userTypeIs "reader"}}
 {{ > reader }}
{{/if}}

Это не сработает само по себе.

Далее вам нужно включить вспомогательную функцию в JS для Template.appbody.userTypeIs

Чтобы сделать это локально, включите их с помощью Template.appbody.helpers()

Template.appbody.helpers({
    ....other helpers....
    userTypeIs: function(t){
          var user = Meteor.user();
          return ( (user) && (user.userType) && (user.userType === t) );
    }

userTypeIs может быть полезен для других шаблонов, поэтому при желании его можно было бы определить глобально для всех шаблонов с помощью Template.registerHelper():

Template.registerHelper('userTypeIs', function(t){
      var user = Meteor.user();
      return ( (user) && (user.userType) && (user.userType === t) );
 }

Обратите внимание, что эта функция возвращает логическое значение для использования с if и принимает параметр, указанный в шаблоне в кавычках. Выполнение использует «защитное программирование» в том смысле, что оно вернет false, если по какой-то причине Meteor.user() или Meteor.user().userType не определены.

Это стандартное шаблонирование в Meteor, нет необходимости импортировать какие-либо дополнительные модули в проект для этой конкретной задачи.

Кроме того, все это находится в документах Meteor API, которые я рекомендую вам прочитать в его полностью, если вы еще этого не сделали.

person Paul    schedule 06.12.2014
comment
Кажется, что это может работать, но это много проверок. Я ломал голову, пытаясь придумать решение, и я думаю, что наконец-то получил его. Пожалуйста, взгляните на мой ответ и дайте мне знать, если вы найдете какие-либо дыры. Эта документация Meteor всегда открыта в одном окне для справки. - person meteorBuzz; 06.12.2014
comment
Чтобы вызвать шаблоны для читателя и издателя, вам нужно {{ >reader }} или {{ > publisher }}, где я поместил элемент списка. Это то, что вы имели ввиду? - person Paul; 06.12.2014
comment
О, я вижу, что ты пытаешься сделать. Дай угадаю, currentUser в этом контексте не определено... - person Paul; 06.12.2014
comment
Пол, да, текущий пользователь определен в {{› UI.dynamic template=currentUser.userType }} - person meteorBuzz; 06.12.2014

Я каким-то образом сломал приложение в состоянии входа в систему и не в состоянии входа в систему. Когда пользователь входит в систему, в зависимости от его userType, я либо отображаю шаблон «читателя», либо шаблон «издателя». Оба они теперь ведут себя как шаблоны макета для каждого пользователя, так сказать. Затем я могу использовать шаблоны в них, используя iron:router.

Router.configure({
layoutTemplate: 'parent',
loadingTemplate: 'appLoading'
});


<template name="parent">
  {{#if currentUser}}
  {{> UI.dynamic template=currentUser.userType }} //this returns 'reader' or 'publisher'
  {{else}}
  {{> notLoggedIn}}
  {{/if}}
</template>

<template name="notLoggedIn">
//unique styling for non logged in users such as join and log in.
{{> yield}}
</template>

<template name="reader">
//unique styling and custom reader navigation menu
{{> yield}}
</template>

<template name="publisher">
//unique styling and custom publisher navigation menu
{{> yield}}
</template>

Теперь я могу рендерить любой шаблон в регион yield из Router.route :))

Router.route('/path', function () {
this.render('templateName');
}
person meteorBuzz    schedule 06.12.2014
comment
Павел, спасибо за поддержку. Иногда чужой метод может подтолкнуть к другой идее ;) - person meteorBuzz; 06.12.2014