`ui-router` $ stateParams与$ state.params

使用ui-router ,可以将$state$stateParams注入到控制器中以访问URL中的参数。 但是,通过$stateParams访问参数只会暴露属于由访问它的控制器pipe理的状态的参数及其父状态,而$state.params包含所有参数,包括任何子状态中的参数。

给定以下代码,如果我们直接加载URL http://path/1/paramA/paramB ,这是控制器加载时的情况:

 $stateProvider.state('a', { url: 'path/:id/:anotherParam/', controller: 'ACtrl', }); $stateProvider.state('a.b', { url: '/:yetAnotherParam', controller: 'ABCtrl', }); module.controller('ACtrl', function($stateParams, $state) { $state.params; // has id, anotherParam, and yetAnotherParam $stateParams; // has id and anotherParam } module.controller('ABCtrl', function($stateParams, $state) { $state.params; // has id, anotherParam, and yetAnotherParam $stateParams; // has id, anotherParam, and yetAnotherParam } 

问题是,为什么区别? 是否有什么最佳做法的指导方针,以及为什么你应该使用,或避免使用其中任何一个?

文档重申您的发现在这里: https : //github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service

如果我的内存服务, $stateParams被引入晚于原始$state.params ,并且似乎是一个简单的辅助注入器,以避免不断写$state.params

我怀疑是否有最佳做法指导方针,但环境胜出。 如果你只是想访问接收到的参数,然后使用$stateParams 。 如果你想知道关于状态更复杂的事情,可以使用$state

使用$state.params另一个原因是非基于URL的状态,在我的脑海里,这个状态非常糟糕,而且非常强大。

我刚刚发现这一点,而不是在URL中公开它,而是在SO上的其他地方回答了一个问题 。

基本上,它允许这种语法:

 <a ui-sref="toState(thingy)" class="list-group-item" ng-repeat="thingy in thingies">{{ thingy.referer }}</a> 

编辑:这个答案是正确的版本0.2.10 。 正如@Alexander Vasilyev所指出的,它在0.2.14版本中0.2.14

使用$state.params另一个原因是当你需要提取像这样的查询参数:

 $stateProvider.state('a', { url: 'path/:id/:anotherParam/?yetAnotherParam', controller: 'ACtrl', }); module.controller('ACtrl', function($stateParams, $state) { $state.params; // has id, anotherParam, and yetAnotherParam $stateParams; // has id and anotherParam } 

我有一个解决某事的根状态。 将$state作为parsingparameter passing将不保证$state.params的可用性。 但使用$stateParams将。

 var rootState = { name: 'root', url: '/:stubCompanyId', abstract: true, ... }; // case 1: rootState.resolve = { authInit: ['AuthenticationService', '$state', function (AuthenticationService, $state) { console.log('rootState.resolve', $state.params); return AuthenticationService.init($state.params); }] }; // output: // rootState.resolve Object {} // case 2: rootState.resolve = { authInit: ['AuthenticationService', '$stateParams', function (AuthenticationService, $stateParams) { console.log('rootState.resolve', $stateParams); return AuthenticationService.init($stateParams); }] }; // output: // rootState.resolve Object {stubCompanyId:...} 

使用“angular”:“〜1.4.0”,“angular-ui-router”:“〜0.2.15”

这两者有很多不同之处。 但是,实际上,我发现,使用$state.params更好。 当你使用越来越多的参数时,这可能会令人困惑,以维护$stateParams 。 如果我们使用多个参数不是URL参数$state是非常有用的

  .state('shopping-request', { url: '/shopping-request/{cartId}', data: {requireLogin: true}, params : {role: null}, views: { '': {templateUrl: 'views/templates/main.tpl.html', controller: "ShoppingRequestCtrl"}, 'body@shopping-request': {templateUrl: 'views/shops/shopping-request.html'}, 'footer@shopping-request': {templateUrl: 'views/templates/footer.tpl.html'}, 'header@shopping-request': {templateUrl: 'views/templates/header.tpl.html'} } }) 

我从一个路由传递前一个状态参数到一个有趣的观察是,$ stateParams被挂起并覆盖了以前的状态parameter passing的前一个路由的状态参数,但是使用$state.param s不行。

当使用$stateParams

 var stateParams = {}; stateParams.nextParams = $stateParams; //{item_id:123} stateParams.next = $state.current.name; $state.go('app.login', stateParams); //$stateParams.nextParams on app.login is now: //{next:'app.details', nextParams:{next:'app.details'}} 

当使用$ state.params时:

 var stateParams = {}; stateParams.nextParams = $state.params; //{item_id:123} stateParams.next = $state.current.name; $state.go('app.login', stateParams); //$stateParams.nextParams on app.login is now: //{next:'app.details', nextParams:{item_id:123}} 

在这篇文章中清楚地解释了: $state服务提供了许多有用的方法来操纵状态以及当前状态的相关数据。 当前的状态参数可以在params键的$state服务上访问。 $stateParams服务返回这个非常相同的对象。 因此, $stateParams服务是一个方便快捷的服务,可以快速访问$state服务上的params对象。

因此,任何控制器都不应该注入$state服务和$stateParams便利服务。 如果只是为了访问当前参数而注入$stateParams ,那么应该重写控制器来注入$stateParams