Загрузка шаблона и контроллера в зависимости от роли пользователя
Хотя технически функция ui-router
templateUrl не поддерживает внедрение сервисов, вы можете использовать templateProvider
для внедрения service
, содержащего переменную role
, или загрузить ее асинхронно, а затем использовать $templateFactory
для возврата содержимого HTML. Рассмотрим следующий пример:
var app = angular.module('app', ['ui.router']);
app.service('session', function($timeout, $q){
this.role = null;
this.loadRole = function(){
//load role using axax request and return promise
};
});
app.config(function($stateProvider, $urlRouterProvider){
$stateProvider.state('dashboard', {
url: '/dashboard',
templateProvider: function(session, $stateParams, $templateFactory){
return session.loadRole().then(function(role){
if(session.role == 'admin'){
return $templateFactory.fromUrl('/admin/dashboard.html', $stateParams);
} else {
return $templateFactory.fromUrl('/user/dashboard.html', $stateParams);
}
});
}
});
$urlRouterProvider.otherwise('/dashboard');
});
Что касается controller
, вы можете указать, что хотите использовать определенный контроллер внутри корневого элемента каждого шаблона с ng-controller
. Или аналогичным образом вы можете использовать параметр controllerProvider
для внедрения service
, который уже будет разрешен role
с помощью templateProvider
. Взгляните на следующий пример опции controllerProvider
внутри определения состояния ui-router
:
controllerProvider: function(session){
if(session.role == 'admin'){
return 'AdminCtrl';
} else {
return 'UserCtrl';
}
}
Конечно, вы можете легко удалить дубликаты из этого кода и определить более доступный микро-DSL, чтобы упростить определение различных правил для определенных ролей и представлений.
Следующая демонстрация должна помочь вам понять код.
Это правильный подход?
Как обычно, это сильно зависит от контекста. Чтобы помочь вам найти ответ, позвольте мне сначала предложить следующие вопросы:
- Насколько различаются представления для ролей?
Собираетесь ли вы скрыть только пару button
и других элементов действия, в основном делая страницу доступной только для чтения для обычных пользователей и редактируемой для суперпользователей? Если изменения будут небольшими, я бы, вероятно, использовал те же представления и скрывал только определенные элементы, возможно, подделывая директиву, подобную ng-if
, которая позволяла бы декларативно включать/отключать определенные функции only-role='operator, admin'
. С другой стороны, если представления будут сильно различаться, использование разных шаблонов может значительно упростить разметку.
- Насколько действия, доступные на конкретной странице, различаются в зависимости от роли?
Отличаются ли действия, внешне похожие на разные роли, внутренней работой? Например, если у вас есть действие Редактировать, доступное как для роли user
, так и для роли admin
, но в одном случае оно запускает мастер как пользовательский интерфейс, а в другом — в сложной форме для опытных пользователей, то есть отдельный controller
имеет больше смысла. С другой стороны, если admin
действия представляют собой надмножество user
действий, то использование одного контроллера кажется более простым. Обратите внимание, что в обоих случаях сохранение controller
вещей окупается — они должны привязывать представления только к поведению, которое инкапсулировано в службах/моделях представлений/моделях/выборе имени
- Будет ли у вас много контекстно отдельных ссылок, ведущих на определенную страницу из разных мест приложения?
Например, возможность обеспечить переход к определенной странице, просто написав ui-sref="dashboard"
независимо от текущего пользователя role
, может быть полезной, если он существует в различных контекстах. Если это так, то их определение в рамках одного маршрута/состояния кажется более удобным для сопровождения, чем условная логика, используемая для построения разных ui-sref
/ng-href
на основе роли. Однако вы также можете динамически определять маршруты/состояния в зависимости от роли пользователя — загружаться динамически или нет
- Будут ли представления и действия, доступные для разных ролей на конкретной странице, развиваться отдельно или вместе?
Иногда мы сначала создаем функции для обычных пользователей, затем для премиальных, а затем для ультимативных. Нет ничего необычного в том, чтобы разделить работу над страницами для user
и admin
между членами команды, особенно если можно легко провести четкие границы. В таком случае, имея отдельные views
и controllers
, разработчики могут просто работать, избегая конфликтов. Конечно, это не все радуги и единороги - команда должна быть очень дисциплинированной, чтобы удалить дублирование, которое, скорее всего, произойдет.
Надеюсь, что мои советы помогут вам определиться.
31.08.2014
admin
— жестко запрограммированная роль. Но я получу роль пользователя асинхронно, используя запрос AJAX. Так что я не уверен, что это сработает:role = injector.get('session').role,
01.09.2014role
01.09.2014