使用ui-router
,可以将$state
或$stateParams
注入控制器以访问URL中的参数。但是,通过$stateParams
访问参数只会公开属于访问它的控制器管理的状态的参数及其父状态,而$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
}
问题是,为什么差异?是否有关于何时以及为何使用或避免使用其中任何一种的最佳实践指南?
答案 0 :(得分:62)
文档重申了您的发现:https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service
如果我的记忆服务,$stateParams
的引入时间晚于原$state.params
,并且似乎是一个简单的助手注入器,以避免连续写$state.params
。
我怀疑有任何最佳实践指南,但背景对我来说是胜利的。如果您只想访问收到的URL中的参数,请使用$stateParams
。如果您想了解关于状态本身的更复杂的事情,请使用$state
。
答案 1 :(得分:19)
使用$state.params
的另一个原因是基于非URL的状态,(在我看来)是非常糟糕且非常强大的。
我在谷歌搜索关于如何传递状态而不必在URL中公开它以及answered a question elsewhere在SO上时发现了这一点。
基本上,它允许这种语法:
<a ui-sref="toState(thingy)" class="list-group-item" ng-repeat="thingy in thingies">{{ thingy.referer }}</a>
答案 2 :(得分:14)
编辑:此答案适用于版本0.2.10
。正如@Alexander Vasilyev指出它在版本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
}
答案 3 :(得分:4)
这两者之间存在许多差异。但在实际工作的同时,我发现更好地使用$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'}
}
})
答案 4 :(得分:3)
我有根状态可以解决问题。传递\u2022
作为解析参数并不能保证$state
的可用性。但是使用$state.params
会。
$stateParams
使用“angular”:“~1.4.0”,“angular-ui-router”:“~0.2.15”
答案 5 :(得分:2)
我将前一个状态参数从一个路径传递到另一个路径时所做的一个有趣的观察是$ stateParams被提升并覆盖先前路由的状态参数,这些参数是使用当前状态参数传递的,但是使用$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}}
答案 6 :(得分:1)
Here清楚地解释了:$state
服务提供了许多有用的方法来操纵状态以及当前状态的相关数据。可以在params键的$state
服务上访问当前状态参数。 $stateParams
服务返回此同一个对象。因此,$stateParams
服务严格来说是一种便捷服务,可以快速访问$state
服务上的params对象。
因此,没有控制器应该同时注入$state
服务及其便利服务$stateParams
。如果仅注入$state
来访问当前参数,则应重写控制器以注入$stateParams
。