Как управлять состоянием с помощью ui-router с несколькими модулями

У меня есть страница приложения с 3 столбцами. Средний столбец является основным видом деятельности и всегда отображается. Два боковых столбца представляют собой списки виджетов, которые имеют свой собственный контроллер и состояния, а также могут быть скрытыми или незакрытыми, а также иметь несколько видов в них. В идеале я бы предположил, что URL-маршруты выглядят следующим образом:

/app - показано основное действие, обе панели скрыты

/app/1234 - показано основное действие, но отображается информация для объекта 1234

/app/1234/leftpanel - основная активность показана с 1234 объектами, а левая панель открыта

/app/1234/leftpanel/list - основная активность показана с 1234 сущностью, а в левой панели отображается вид списка

/app/leftpanel/list - основная активность показывает состояние по умолчанию, левая панель все еще показывает список

Возможно ли это установить с помощью ui-router? Я видел этот пример:

https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions

который показывает, как использовать $stateProvider между несколькими модулями, но я все еще не вижу, как сделать этот сценарий работы -

Ответы

Ответ 1

Я решил проблему. Я также опубликовал об этом в angular -ui github, и их ответ был в основном: "ну, на самом деле, это не то, для чего был разработан маршрутизатор, поэтому, если вы хотите, чтобы" фанатное "управление состоянием, поместите данные в параметрах и посмотреть на них самостоятельно и реализовать любую логику, в которой вы нуждаетесь". Я вроде как чувствовал, что это то, для чего был разработан ui-router, поэтому я немного расширил его (без изменений исходного кода), чтобы выполнить это. Решение представляет собой комбинацию абстрактных состояний, фальшивое "выключенное" состояние, параметры в URL-адресах маршрутизатора и расширение услуги $urlRouterProvider.

Сначала расширьте $urlRouterProvider:

urlRouterProvider.when(/^((?!leftpanel).)*$/, ['$state', '$location', function ($state, $location) {
 //we've got just /app or /app/3434, nothing that contains /leftpanel, so turn off    
 $state.transitionTo("off");
   }]);

Затем добавьте это состояние "off":

$stateProvider.state('off',{
 //url: //there is no url
 views:{
   container:{
     template: 'blank',
     controller:['$scope', '$stateParams', function($scope, $stateParams){
       console.log("off yay"); //just for sanity, not necessary
     }]
   }
 }});

Затем настройте остальную часть маршрутизации приложения:

appModule.constant('LEFT_PANEL_STATES', function() {

var leftPanelRoot = { 
  name: 'root.leftpanel',  //mandatory
  template: '',
  url: "/app/:primaryId/leftpanel",
  views:{
      '[email protected]': {
          templateUrl: "partials/leftpanel_container_partial.html",
          controller:"LeftPanelRootCtrl",
          resolve: {
            //etc
          }
      }
  },
   "abstract":true //makes this view only viewable from one of its child states
};

var leftPanelItemsList = {
  name: 'root.leftpanel.itemslist',  //mandatory
  parent: leftPanelRoot,  //mandatory
  url: "/items-list",
  views:{
      '[email protected]': {
          templateUrl: "partials/leftpanel_items_list.html",
          controller:"LeftPanelItemsListCtrl",
          resolve: {
           //etc
          }
      }
  }};


 var leftPanelListDetail = {
name:"root.leftpanel.itemslist.detail",
parent:leftPanelItemsList,
url:"/:id/detail",
views:{
  "detail":{
    templateUrl:"partials/leftpanel_item_detail.html",
    controller:"LeftPanelItemListDetailCtrl"
  }
}};

  var leftPanelExtendedDetailList = {
name:"root.leftpanel.itemslist.extendedlist",
parent:leftPanelItemsList,
url:"/:id/extendedDetail/list", 
views:{
  "extendeddetaillist":{
    templateUrl:"partials/leftpanel_extended_detail_list.html",
    controller:"LeftPanelExtendedDetailListCtrl"
  }
}};