如何使用具有多个模块的ui-router管理状态

时间:2013-08-02 14:25:25

标签: angularjs angular-ui angular-ui-router

我有一个包含3列的应用页面。中间列是主要活动,始终显示。两个侧面列是小部件列表,它们有自己的控制器和状态,可以是隐藏的也可以是非隐藏的,并且在它们中也有多个视图。理想情况下,我想象网址如下:

/ 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 个答案:

答案 0 :(得分:7)

我确实解决了这个问题。我也在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:{
      'childview@root.leftpanel': {
          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"
  }
}};