Angularjs ui-router - как создать главное состояние, которое является глобальным через приложение

<html ng-app="app">
<head>
...
</head>
<body>
  <div id="header"></div>
  <div id="notification"></div>
  <div id="container"></div>
  <div id="footer"></div>
</body>
</html>

С данной структурой приложения (полученным из angular -app):

  • header: Здесь находится панель навигации по сайту, панель входа/выхода и т.д. Это динамический и имеет собственный контроллер.
  • уведомление: глобальный контейнер уведомлений.
  • container: Это был мой <ng-view>. Таким образом, здесь загружаются все остальные модули.
  • нижний колонтитул: глобальный нижний колонтитул.

Как выглядит государственная иерархия? Я прошел через пример, который показывает один модуль (контакты), но обычно приложение будет иметь глобальное (корневое) состояние и внутри корневого состояния отображаются другие состояния модуля.

Я думаю, что мой модуль app, вероятно, имеет состояние root, а затем каждый модуль должен иметь собственное состояние, и я должен наследовать от состояния root. Я прав?

Также из примера ui-state они использовали как $routeProvider, так и $urlRouterProvider, а также $stateProvider определил url. Я понял, что $stateProvide также обрабатывает маршрутизацию. Если я ошибаюсь, какой провайдер должен использовать для маршрутизации?

EDIT: http://plnkr.co/edit/wqKsKwFq1nxRQ3H667LU?p=preview

Спасибо!

Ответ 1

Подход, который вы использовали в вашем плункере, близок. @ben-schwartz демонстрирует, как вы задали значения по умолчанию в своем корневом состоянии для трех существенно статических представлений. Отсутствие в вашем плункере состоит в том, что вашим дочерним состояниям все равно необходимо ссылаться на вид верхнего контейнера.

   .state('root',{
      url: '',
      views: {
        'header': {
          templateUrl: 'header.html',
          controller: 'HeaderCtrl'
        },
        'footer':{
          templateUrl: 'footer.html'
        }
      }
    })
    .state('root.about', {
      url: '/about',
      views: {
        '[email protected]': {
          templateUrl: 'about.html'
        }
      }
    });    

Примечание views: { '[email protected]': ...} вместо templateUrl: ... в 'root.about'

То, о чем вы также можете спросить, это то, могут ли модули определить свои собственные состояния, которые затем присоединяются к иерархии состояний приложения. Тип плагинов для маршрутов/состояний каждого модуля обеспечивает.

Чтобы достичь этого, вы будете тесно связывать свои модули с основным приложением.

В модуле:

angular.module('contact', ['ui.router'])
  .constant('statesContact', [
      { name: 'root.contact',
        options: {
          url: 'contact',
          views: {
            '[email protected]': {
              templateUrl: 'contacts.html'
            }
          },
          controller:'ContactController'
      }}
    ])
  .config(['$stateProvider', function($stateProvider){    
  }])

Затем в приложении:

var app = angular.module('plunker', ['ui.router', 'contact']);
app.config(       ['$stateProvider', 'statesContact', 
           function($stateProvider,   statesContact){
    $stateProvider
    .state('root',{ ... })
    .state('root.home', { ... })
    .state('root.about', { ... })
    angular.forEach(statesContact, function(state) {
      $stateProvider.state(state.name, state.options);
    })      
}]);

Это означает, что все ваши модули должны быть совместимы с этим шаблоном, указанным в вашем приложении. Но если вы примете это ограничение, вы можете выбрать любую комбинацию своих модулей, и их состояния волшебным образом добавятся в ваше приложение. Если вы хотите стать еще более привлекательным, вы можете изменить state.options.url в своем цикле statesModuleName, чтобы, например, префикс вашей структуры URL-модуля.

Также обратите внимание, что модуль ui.compat необходим только при переходе от $routeProvider в $stateProvider. Обычно вы должны использовать ui.state.

Также не забудьте отрегулировать в header.html $state.includes('root.contact'))

обновленный плункер

Ответ 2

Несмотря на запутанность, часто задаваемые вопросы в wi-router wiki говорят, что это невозможно: ui-router/wiki/faq

Один из подходов состоит в том, чтобы позволить каждой функции определять его собственное корневое состояние (как в этом примере: Управление состоянием AngularJS с помощью ui-router)

Другим было бы определение всей иерархии состояний в вашем модуле "myApp" и просто управление контроллерами и т.д. из зависимых модулей. Это работает особенно хорошо, когда вы поддерживаете мобильный и настольный сайт; определить иерархию состояний сайта в модуле mobileApp и desktopApp и иметь функциональные возможности (например, контроллеры, службы и т.д.), разделяемые в отдельных модулях.

Ответ 3

Это зависит от того, как вы предпочитаете подходить к нему.

Все области наследуют от rootScope, поэтому вы можете разместить там глобальное состояние. В литературе NG упоминается, что вы должны указывать только глобальное состояние, а не функциональность. Функциональность, требуемая для всей системы, относится к услугам, и, в частности, вы не должны внедрять службы, единственной целью которых является сохранение состояния. Все советы, как представляется, неявно разделяются в контексте того, как это облегчает или затрудняет вашу способность легко выполнять сквозное тестирование.