Как управлять состоянием с помощью 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/Частозадаваемыевопросы

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


person chrismarx    schedule 02.08.2013    source источник
comment
Вы что-нибудь придумали? Я действительно очень хочу знать, как это сделать. Я добавил здесь проблему, github.com/angular-ui/ui-router/ вопросы/306   -  person Matt Broekhuis    schedule 12.08.2013
comment
Моя теория заключается в том, что если бы вы могли иметь состояние пользовательского интерфейса, независимое от корневой области, вы могли бы иметь детальный контроль внутри модуля. Однако, похоже, это напрямую связано с $rootScope...   -  person Matt Broekhuis    schedule 12.08.2013
comment
Вы когда-нибудь решали эту проблему?   -  person J.P. Armstrong    schedule 28.01.2014
comment
Смотрите опубликованный ответ-   -  person chrismarx    schedule 13.03.2014


Ответы (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");
   }]);

Затем добавьте это состояние «выключено»:

$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:{
      'container@': {
          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"
  }
}};
person chrismarx    schedule 28.01.2014
comment
Я видел несколько случаев, когда я пытался заставить ui-router сделать что-то подобное, и ответ команды разработчиков был в основном таким же. - person Brian Vanderbusch; 17.02.2014