使用Angular UI路由器的$ stateProvider在状态上声明主控制器

时间:2014-05-05 12:38:49

标签: javascript angularjs routes url-routing angular-ui-router

我刚刚开始使用UI路由器,主要是因为能够声明嵌套状态和命名视图。

以下是我如何配置两者组合的简化示例:

$stateProvider.state("page", {
  abstract: true,
  templateUrl: "page.html"
})
.state("page.stream", {
  url: "/stream",
  controller: "StreamCtrl",
  views: {
    content: {
      templateUrl: "stream-content.html"
    },
    header: {
      templateUrl: "stream-header.html"
    }
  }
})
.state("page.notifications", {
  url: "/notifications",
  controller: "NotifsCtrl",
  views: {
    content: {
      templateUrl: "notifs-content.html"
    },
    header: {
      templateUrl: "notifs-header.html"
    }
  }
})

我已宣布page视图是抽象的,因为它的唯一目的是保存另外两个视图,即变量headercontent,以及静态导航跨页。

<!-- page.html -->
<nav>...</nav>
<div ui-view="header"></div>
<div ui-view="content"></div>

路由和插入模板按预期工作,导航到/stream/notifications时导航保持静态,标题和内容视图也会发生变化。但是,page.streampage.notifications上声明的控制器无法启动。

我的第一个直觉是将状态配置的视图对象与控制器一起声明会导致控制器在整个页面上设置,因此标题和内容将共享控制器{{{ 1}}。

声明控制器处于$scope状态可实现此目的,但使用page并不能让我获取足够的信息来决定使用哪个控制器:

controllerProvider

在声明视图名称时,我尝试使用不同的符号(绝对/相对),我对以下内容感到满意:

$stateProvider.state("page", {
  abstract: true,
  templateUrl: "page.html",
  controllerProvider: function ($stateParams) {
    // How do I know which state I am in, notifications or stream?
    return ???
  }
})

这确实在整个页面上设置了StreamController,但导致两个模板都丢失,就像从未加载过$stateProvider.state("page.stream", { url: "/stream", views: { // I understand that this targets the parent page which holds both header and content "@": { controller: "StreamController" }, page: {...} header: {...} } }) 一样。

我应该在每个页面子状态上设置控制器,以便子状态中的每个视图共享控制器的$ scope?

2 个答案:

答案 0 :(得分:2)

我也无法初始化控制器。您可以拥有stream.html和notifs.html以及ng-include模板。如果页面与常见和不常见的部分混合,我可以看到它是多么令人讨厌

 .state("page", {
   abstract: true,  
   controller: 'PageCtrl'     
   templateUrl: 'page.html',    
  })
.state("page.stream", {
  url: "/stream",
  controller: 'StreamCtrl',
  templateUrl: 'stream.html'  
})
.state("page.notifications", {
  url: "/notifications",
  controller: 'NotifsCtrl',
  templateUrl: 'notifs.html'
  })


<!-- page.html -->
<nav>...</nav>
<div ui-view></div>

<!-- stream.html-->
<span>stream-header</span>
<div ng-include='"commonthings.html"'></div>
<span>stream-content.html</span>

<!-- notifs.html-->
<span>notifs-header</span>
<div ng-include='"commonthings.html"'></div>
<span>notifs-content.html</span>

每个控制器正确初始化

答案 1 :(得分:0)

尝试在单个状态下实例化多个视图的正确语法如下。 (您必须在每个视图中包含控制器。)

.state("page.notifications", {
  url: "/notifications",
  views: {
    content: {
      templateUrl: "notifs-content.html",
      controller: "NotifsCtrl"
    },
    header: {
      templateUrl: "notifs-header.html"
      controller: "NotifsHeaderCtrl"
    }
  }
})
...

如果您正在寻找要包含在/stream/notifications中的控制器,那么只需将其包含在page状态。

$stateProvider.state("page", {
  abstract: true,
  templateUrl: "page.html",
  controller: "PageCtrl"
})