`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
。