$ routeParams在主控制器中为空

Der*_*ang 23 angularjs

我有这个布局html:

<body ng-controller="MainController">
  <div id="terminal"></div>

  <div ng-view></div>

  <!-- including scripts -->
</body>
Run Code Online (Sandbox Code Playgroud)

显然,当我尝试使用它$routeParamsMainController,它总是空的.重要的是要注意,MainController应该在每个可能的路线中生效; 因此我没有在我的app.js中定义它.我的意思是,我不是在这里定义它:

$routeProvider.when("/view1", {
  templateUrl: "partials/partial1.html"
  controller: "MyCtrl1"
})

$routeProvider.when("/view2", {
  templateUrl: "partials/partial2.html"
  controller: "MyCtrl2"
})

// I'm not defining MainController here!!
Run Code Online (Sandbox Code Playgroud)

事实上,我认为我的问题与此问题完全相同:https://groups.google.com/forum/#!topic/angular/ib2wHQozeNE

但是,我仍然没有得到如何在我的主控制器中获取路由参数...

编辑:

我的意思是我没有将我的MainController与任何特定路线相关联.它的定义; 它是所有其他控制器的父控制器.我想知道的是,当你去一个像/whatever路由匹配的URL时/:whatever,为什么只有子控制器能够访问路由参数,而主控制器不是?如何:whatever在主控制器中获取route参数?

Ian*_*nce 71

$routeParams服务是异步填充的.这意味着它首次在控制器中使用时通常显示为空.

$routeParams在填充时收到通知,请订阅该$routeChangeSuccess活动$scope.(如果您所在的组件无法访问孩子$scope,例如服务或工厂,则可以注入并使用$rootScope.)

module.controller('FooCtrl', function($scope, $routeParams) {
  $scope.$on('$routeChangeSuccess', function() {
    // $routeParams should be populated here
  });
);
Run Code Online (Sandbox Code Playgroud)

路由使用的控制器或路由包含的模板内的控制器将立即访问完全填充的$routeParams因为在继续之前ng-view等待$routeChangeSuccess事件.(它必须等待,因为它需要路由信息才能确定哪个模板/控制器甚至可以加载.)

如果您知道您的控制器将在其中使用ng-view,则无需等待路由事件.如果你知道你的控制器不会,你会的.如果你不确定,你必须明确允许这两种可能性.订阅$routeChangeSuccess是不够的; 如果$routeParams尚未填充,您将只看到该事件:

module.controller('FooCtrl', function($scope, $routeParams) {
  // $routeParams will already be populated
  // here if this controller is used within ng-view

  $scope.$on('$routeChangeSuccess', function() {
    // $routeParams will be populated here if
    // this controller is used outside ng-view
  });
);
Run Code Online (Sandbox Code Playgroud)

  • 这应该是公认的答案!谢谢. (5认同)

Edu*_*nal 0

你这里至少有两个问题:

  • 你得到$routeParams了你没有定义的路由参数

  • 定义主控制器的文件并不重要。重要的是在哪个模块/功能中

参数必须使用$routeProvider语法定义:paramName

$routeProvider.when("/view2/name1/:a/name2/:b"
Run Code Online (Sandbox Code Playgroud)

然后您可以使用 检索它们$routeParams.paramName

您还可以使用查询参数,例如index.html?k1=v1&k2=v2.

app.js是您通常定义依赖项和配置的文件(这就是您在那里拥有应用程序模块.config块的原因)并且它包含应用程序模块:

var myapp = angular.module(...);
Run Code Online (Sandbox Code Playgroud)

该模块可以将其他模块作为依赖项,例如指令或服务,或者每个功能一个模块。一个简单的方法是使用一个模块来封装控制器。一种更接近原始代码的方法是将至少一个控制器放在主模块中:

myapp.controller('MainCtrl', function ($scope) {...}
Run Code Online (Sandbox Code Playgroud)

也许您将控制器定义为全局函数?function MainCtrl() {...}?这会污染全局命名空间。躲开它。

在主模块中定义控制器不会使其“在所有路由中生效”。这必须通过主控制器来定义 $routeProvider或使每个路由的控制器“继承”主控制器。这样,每个路线的控制器都会在路线更改ng-controller="MainCtrl"实例化,而主控制器仅在到达线路时实例化一次(仅在应用程序启动期间发生一次)