0

AngularJS - UI Router - Программное добавление состояний

16

Существует ли способ программно добавлять состояния в $stateProvider после конфигурации модуля, например, из сервиса?

Чтобы дать больше контекста к этому вопросу, у меня есть ситуация, в которой я могу выбрать один из двух подходов:

  1. Попробовать принудительно перезагрузить состояние, определенное в конфигурации модуля. Проблема в том, что для этого состояния установлен параметр 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,
})
  1. Попробовать программно добавить состояния, которые мне нужны для загрузки из сервиса, чтобы маршрутизация работала правильно. Я бы предпочел использовать первый вариант, если это возможно.

2 ответ(ов)

0

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');

}]);

Таким образом, вы можете легко расширить функционал своего приложения, делая его более структурированным и поддерживаемым.

0

Да, это возможно сделать, но из-за наличия слоев кэширования процесс будет сложным. Алекс Фейнберг описал решение на своем блоге здесь:

http://alexfeinberg.wordpress.com/2014/03/08/dynamically-populating-angular-ui-router-states-from-a-service/

В конце статьи приведен пример создания состояния с помощью 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'
});
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь