【问题标题】:Declaring a master controller on a state with Angular UI router's $stateProvider使用 Angular UI 路由器 $stateProvider 在状态上声明主控制器
【发布时间】:2014-05-05 12:38:49
【问题描述】:

我刚刚开始玩 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 上声明的控制器不会被启动。

我的第一个直觉是,在状态配置的视图对象旁边声明一个控制器会导致在整个页面上设置控制器,因此标题和内容将共享控制器的 $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 ???
  }
})

在声明视图名称时,我尝试使用不同的表示法(绝对/相对),并且我在以下方面取得了一些运气:

$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: {...}
  }
})

这确实在整个页面上设置了 StreamController,但导致两个模板都丢失了,好像从未加载过 page.html

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

【问题讨论】:

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


    【解决方案1】:

    我也无法初始化控制器。您可以拥有 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>
    

    每个控制器都正确初始化

    【讨论】:

      【解决方案2】:

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

      .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"
      })
      

      【讨论】:

      • 谢谢,但这并没有给我我需要的东西——我想要一个PageCtrl,就像你描述的那样,是的,这样它就可以控制标题和内容视图,但我需要这个控制器是动态的 -- NotifsCtrlpage.notificationsStreamCtrlpage.stream 时。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多