AngularJS - UI Router - Программное добавление состояний
Существует ли способ программно добавлять состояния в $stateProvider после конфигурации модуля, например, из сервиса?
Чтобы дать больше контекста к этому вопросу, у меня есть ситуация, в которой я могу выбрать один из двух подходов:
- Попробовать принудительно перезагрузить состояние, определенное в конфигурации модуля. Проблема в том, что для этого состояния установлен параметр reloadOnSearch в false, так что когда я пытаюсь выполнить $state.go('state.name', {new:param}, {reload:true});, ничего не происходит. Есть идеи?
Определение состояния:
.state('index.resource.view', {
url: "/:resourceName/view?pageNumber&pageSize&orderBy&search",
templateUrl: "/resourceAdministration/views/view.html",
controller: "resourceViewCtrl",
reloadOnSearch: false,
})
- Попробовать программно добавить состояния, которые мне нужны для загрузки из сервиса, чтобы маршрутизация работала правильно. Я бы предпочел использовать первый вариант, если это возможно.
2 ответ(ов)
Chris T действительно прав! Использование провайдера — это правильное решение. Вам не нужно добавлять его в объект window
, это более защищённый и удобный подход.
Сопоставление его ответа с этой статьёй действительно помогло: Различия между провайдерами в AngularJS.
Такое решение предоставляет доступ к конфигурации модуля $stateProvider
в блоке конфигурации других модулей во время их выполнения.
В моём случае я динамически создаю состояния панели управления в зависимости от разрешений пользователя.
В блоке конфигурации устанавливается мой провайдер, передавая stateProvider
модуля (для доступа позже).
// в dashboard.module.js
var dashboardModule = angular.module('app.modules.dashboard', [
'app.modules.dashboard.controllers',
'app.modules.dashboard.services',
'app.modules.dashboard.presentations.mileage'
])
.provider('$dashboardState', function($stateProvider) {
this.$get = function(PATHS, $state) {
return {
addState: function(title, controllerAs, templatePrefix) {
$stateProvider.state('dashboard.' + title, {
url: '/' + title,
views: {
'dashboardModule@dashboard': {
templateUrl: PATHS.DASHBOARD + (templatePrefix ? templatePrefix + '/' : '/') + title + '/' + title + '.view.html',
controller: controllerAs ? controllerAs : null
}
}
});
}
}
}
});
Это сделает провайдер состояний панели управления доступным для других модулей, вместо того чтобы добавлять его в объект window
.
Затем в блоке выполнения модуля пользователя (контроллер) я могу получить доступ к провайдеру состояний панели управления и динамически добавлять состояния.
var UserControllers = angular.module('app.modules.user.controllers', [])
.controller("UserLoginController", ["$state", "$dashboardState", function($state, $dashboardState) {
$dashboardState.addState('faq', null, 'content');
$state.go('dashboard.faq');
}]);
Таким образом, вы можете легко расширить функционал своего приложения, делая его более структурированным и поддерживаемым.
Да, это возможно сделать, но из-за наличия слоев кэширования процесс будет сложным. Алекс Фейнберг описал решение на своем блоге здесь:
В конце статьи приведен пример создания состояния с помощью stateProvider:
app.stateProvider.state(ent.lob.name.toLowerCase(), {
url: '/' + ent.lob.name.toLowerCase(),
controller: ent.lob.name.toLowerCase() + 'Controller',
templateUrl: 'lobs/views/' + ent.lob.name.toLowerCase() + '.html'
});
В чем разница между angular-route и angular-ui-router?
Работа с $scope.$emit и $scope.$on в AngularJS
Как привязать значения списка чекбоксов в AngularJS?
Как установить свойство value в ng-options AngularJS?
AngularJS - Условное использование атрибутного директивы