Независимая маршрутизация для нескольких регионов в одностраничном приложении AngularJS

У меня одностраничное приложение AngularJS с четырьмя регионами, каждое со своим содержимым:

Page Layout

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

Я попытался сделать это (plunkr) с angular -ui-router, но я не могу понять, как создавать состояния angular -ui, которые влияют только на конкретный модуль или область, не изменяя остальные регионы на странице.

Страница содержит области:

<body>
  <a ui-sref="initial1">Initial Region 1</a><br/>
  <a ui-sref="initial2">Initial Region 2</a>

  <div ui-view="region1" class="region1"></div>
  <div ui-view="region2" class="region2"></div>
</body>

И приложение пытается определить каждую область в независимом модуле:

var app = angular.module('Main', ['ui.router', 'Region1', 'Region2']);

var region1App = angular.module('Region1', []);

region1App.config(function($urlRouterProvider, $stateProvider) {
  $urlRouterProvider.otherwise("/");
  $stateProvider
    .state('initial1', {
      url: '/',
      views: {
        '[email protected]': {
          template: 'Initial Region 1 State, go to <a ui-sref="second1">Second State</a>'
        }
      }
    })
    .state('second1', {
      url: '/',
      views: {
        '[email protected]': {
          template: 'Second Region 1 State, go to <a ui-sref="initial1">Initial State</a>'
        }
      }
    });
});

var region2App = angular.module('Region2', []);

region2App.config(function($urlRouterProvider, $stateProvider) {
  $urlRouterProvider.otherwise("/");
  $stateProvider
    .state('initial2', {
      url: '/',
      views: {
        '[email protected]': {
          template: 'Initial Region 2 State, go to <a ui-sref="second2">Second State</a>'
        }
      }
    })
    .state('second2', {
      url: '/',
      views: {
        '[email protected]': {
          template: 'Second Region 2 State, go to <a ui-sref="initial2">Initial State</a>'
        }
      }
    });
});

Каждый модуль должен иметь свое собственное "начальное" состояние и "второе" состояние, и оба должны отображаться на экране одновременно, а изменение состояния одного не должно влиять на другое. Если это не возможно сделать с помощью angular -ui-router, что лучший способ сделать это с помощью Angular?

Ответ 1

Вы можете использовать UI-Router Extras - Липкие состояния для достижения своей цели.

Вам понадобится один с именем <div ui-view='name'></div> для каждого региона. Затем добавьте sticky: true к определению состояния, которое предназначено для этой области с именем view.

<div ui-view="region1"></div>
<div ui-view="region2"></div>
<div ui-view="region3"></div>
<div ui-view="region4"></div>


.state('state1', {
  sticky: true,
  views: { region1: { templateUrl: 'foo.html', controller: barCtrl } }
}
.state('state2', {
  sticky: true,
  views: { region2: { templateUrl: 'foo2.html', controller: bar2Ctrl } }
}
.state('state3', {
  sticky: true,
  views: { region3: { templateUrl: 'foo3.html', controller: bar3Ctrl } }
}
.state('state4', {
  sticky: true,
  views: { region4: { templateUrl: 'foo4.html', controller: bar4Ctrl } }
}

Существует демоверсия, в которой вы можете посмотреть, как это работает. Примечание: демо использует вкладки и соответственно отображает/скрывает пользовательский интерфейс. В вашем сценарии использования нет необходимости показывать/скрывать каждое именованное представление.

Проверьте демонстрационный исходный код для получения дополнительной информации.

Ответ 2

Я создал отдельное приложение angular для каждого региона. Связь между приложениями осуществляется путем получения ссылки на соответствующую область с помощью элемента app в DOM и отправки события через angular.element(document.getElementById('RegionX_App')).scope().$emit в качестве показанного здесь.

UPDATE: Я закончил использование Sticky States в дополнительных интерфейсах UI-Router, как описано в ответ от Chris T, и он отлично работал.