无论如何使用Angular UI路由器为每条路由指定默认参数?
通过选择用户然后导航到我的应用程序,通过其他应用程序的上下文输入我的应用程序。我的应用程序中的URL将始终在URL中具有用户ID,以便人们可以为URL添加书签,通过电子邮件发送等等。因此,当您浏览时,URL始终遵循以下方案:
#/{userId}/view/...
#/{userId}/edit/...
等。
对于他们前往的任何路线,此appId对于应用内部的用户始终是相同的。如果他们碰巧注销,请返回主应用程序,选择一个新用户并返回我的应用程序,此userId将更改,但每个路径的值将相同。
无论如何从服务/工厂读取这个值,然后将其插入每条路线?
编辑:
我应该提一下,当我导航到某个状态时,我希望避免在每个路由上显式设置此参数。例如,每次我导航到新状态时,我都不想做ui-sref="new-state({userId : blah})"
。 userId永远不会在我的应用程序的上下文中更改。
再次编辑:
我实际上是以不同的方式解决了这个问题,即不必发送' userId'手动到每条路线。我没有使用指令,而是使用$ provide.decorator将此功能添加到' go'方法。我在下面的回答中添加了一个答案。
答案 0 :(得分:7)
您可以声明子状态继承的抽象父状态:
$stateProvider
.state('user', {
url: '/:userid',
abstract: true,
resolve:
// assuming some kind of User resource factory
currentUser: function($stateParams, User) {
return User.get($stateParams.userid);
}
}
})
.state('user.view', {
url: '/view', // actual url /:userid/view
controller: function($scope, currentUser) {
// currentUser resource available
}
});
.state('user.edit', {
url: '/edit', // actual url /:userid/edit
controller: function($scope, currentUser) {
// currentUser resource available
}
});
在导航到州时,您需要传入所需的用户:
$state.go('user.view', {userid: 'myuserid'});
因此,在currentUser服务上创建某种.go()
包装器方法可能是有意义的,这样您就不必每次都指定用户ID。
<强>更新强>
要解决编辑中发布的问题,您可以引入如下指令:
angular.module('app')
.directive('userSref', function($state) {
return function(scope, elem, attrs) {
var state = 'user.' + attrs.userSref;
elem.bind('click', function() {
$state.go(state, {userid: $state.params.userid});
});
scope.$on('$destroy', function() {
elem.unbind('click');
});
};
});
然后,任何将来基于用户的状态的链接都可以通过以下方式完成:
<a user-sref="view">View User</a>
答案 1 :(得分:3)
我没有编写处理userID自动发送的指令,而是使用$provide.decorator
,如下所示:
app.config(['$provide',
function($provide) {
$provide.decorator('$state', function($delegate, UserService) {
// Save off delegate to use 'state' locally
var state = $delegate;
// Save off reference to original state.go
state.baseGo = state.go;
// Decorate the original 'go' to always plug in the userID
var go = function(to, params, options) {
params.userID = UserService.userID;
// Invoke the original go
this.baseGo(to, params, options);
};
// assign new 'go', decorating the old 'go'
state.go = go;
return $delegate;
});
}
]);
我从这篇文章中得到了这个想法:
Changing the default behavior of $state.go() in ui.router to reload by default
答案 2 :(得分:-1)
您可以使用&#34;嵌套状态&#34;和&#34;解决&#34; UI-Router的功能,用于在应用中创建状态层次结构。您将定义解析userId
的顶级状态。然后定义任意数量的子状态,它们将自动继承&#34;已解决的&#34; userId
。
查看this page of the documentation,特别是标题为&#34;重要$ stateParams Gotcha&#34;的部分。我将在此处粘贴该页面中的两个代码段。
方法不正确:
$stateProvider.state('contacts.detail', {
url: '/contacts/:contactId',
controller: function($stateParams){
$stateParams.contactId //*** Exists! ***//
}
}).state('contacts.detail.subitem', {
url: '/item/:itemId',
controller: function($stateParams){
$stateParams.contactId //*** Watch Out! DOESN'T EXIST!! ***//
$stateParams.itemId //*** Exists! ***//
}
})
使用&#34;解决&#34;
的正确方法$stateProvider.state('contacts.detail', {
url: '/contacts/:contactId',
controller: function($stateParams){
$stateParams.contactId //*** Exists! ***//
},
resolve:{
contactId: ['$stateParams', function($stateParams){
return $stateParams.contactId;
}]
}
}).state('contacts.detail.subitem', {
url: '/item/:itemId',
controller: function($stateParams, contactId){
contactId //*** Exists! ***//
$stateParams.itemId //*** Exists! ***//
}
})
自&#34; contactId&#34;参数由父状态解析,子状态将继承该状态。