据我了解ui.router
你有$ stateProvider
在其中你可以写$ stateProvider.state()
你可以写
.state('account', {
url: '/account',
template: '<ui-view/>'
})
.state('account.register', {
url: '/register',
templateUrl: '/account/views/register.html',
data: { title: 'Create Account' },
controller: 'AccountRegister'
})
但'account'是某种根状态的孩子。
所以我的想法是,ui.router的根状态有一个<ui-view/>
,就像'account'
有模板'<ui-view/>'
一样,所以index.html就是根状态。即使是'home'
url: '/'
,$http.get('/api/user/status')
也会是这个根状态的孩子。
如果我能够访问根状态并说它应解析用户服务,则此解析值应该在所有状态上可用(或者更好地在每个状态是根状态的子状态,也就是所有状态)。用户服务承诺生成{"user":{id: "userid", role: "role"}} or {"user":null}
并返回User.get()
这将保证始终填充用户服务返回的值。
如何访问根状态并说它应该解决,例如{{1}}?
或者让我重新说一下。
所有控制器都应该可以使用用户对象。 有关当前登录用户的信息由$ http.get('/ api / user / status')提供 这就是问题,我正在寻找一个DRY解决方案,假设api正在服务,假设用户对象设置是100%安全,也就是承诺总是满足,也就是“等待承诺在继续之前解决”
答案 0 :(得分:5)
免责声明 - 弄乱你的根范围不是一个好主意。如果你正在阅读这篇文章,请注意OP,@ dalu已经完成了这条路线,并用http拦截器解决了他的问题。仍然 - 回答这个问题非常有趣,所以你可能喜欢自己尝试一下:
可能有点晚了,但是这里有了
正如评论中提到的,根据我迄今为止的经验,这与ui-router的api(v0.2.13
)无法实现,因为他们已经声明了真正的根状态,名为""
。 Looks like there's been a pull request in for the past couple years about what you're looking for,但它看起来不像是在任何地方。
根状态的属性如下:
{
abstract: true,
name: "",
url: "^",
views: null
}
也就是说,如果您想扩展路由器以添加此功能,您可以通过装饰$stateProvider
来轻松完成此操作:
$provide.decorator('$state', function($delegate) {
$delegate.current.resolve = {
user: ['User', '$stateParams', httpRequest]
};
return $delegate
});
请注意,有两个current
s:$delegate.current
- 原始""
州 - 和$delegate.$current
- 其包装。
$stateChangeStart
上的事件处理好,或者使某些"top"
状态更好。我可以想到三个解决方案:
我想,最后,我有义务提醒你要注意你在根级工作的事实。所以,我的意思是,在根级别做任何事情时要小心。
我希望这能回答你的问题!
答案 1 :(得分:5)
从ui-router 1.0.0-beta.3
开始,您现在可以使用转换挂钩轻松完成此操作:
angular
.module('app')
.run(run);
function run($transitions, userService) {
// Load user info on first load of the page before showing content.
$transitions.onStart({}, trans => {
// userService.load() returns a promise that does the job of getting
// user info and populating a field with it (you can do whatever you like of course).
// Just remember to finally return `true`.
return userService
.load()
.then(() => true);
});
}
在继续加载州之前,州经理将等待承诺解决。
重要提示:确保userService
仅加载一次数据,当它已经加载时,它应该只返回已解决的保证。因为上面的回调将在每个状态转换时调用。例如,要处理登录/注销,您可以创建userService.invalidate()
并在执行登录/注销后但在执行$state.reload()
之前调用它。
答案 2 :(得分:0)
这是不同的方法
将以下代码添加到您应用的.run
阻止
// When page is first loaded, it will emit $stateChangeStart on $rootScope
// As per their API Docs, event, toState, toParams, fromState values can be captured
// fromState will be parent for intial load with '' name field
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState){
// check if root scope
if(fromState.name == ''){
// add resolve dependency to root's child
if(!toState.resolve) toState.resolve = {};
toState.resolve.rootAuth = ['$_auth', '$q', '$rootScope', function($_auth, $q, $rootScope){
// from here on, imagine you are inside state that you want to enter
// make sure you do not reject promise, because then you have to use
// $state.go which will again call state from root and you will end up here again
// and hence it will be non ending infinite loop
// for this example, I am trying to get user data on page load
// and store in $rootScope
var deferred = $q.defer();
$_auth.user.basic().then(
function(authData){
// store data in rootscope
$rootScope.authData = authData;
deferred.resolve(authData);
console.log($rootScope.authData);
},
function(){
$rootScope.authData = null;
deferred.resolve(null);
console.log($rootScope.authData);
}
);
return deferred;
}];
}
});
如果您需要刷新状态更改$state.go('name', {}, {reload:true});
,请使用authData
方法(以便过渡状态始终从root
开始,否则解决加载authData
永远不会调用一旦root被加载,它永远不需要再次被调用{除了页面重新加载}。)。
答案 3 :(得分:-1)
在状态定义中使用resolve
属性。
.state('root', {
resolve: {
user: ['$http', function($http) {
return $http.get('/api/user/status')
}]
},
controller: function($scope, user) {
$scope.user = user; // user is resolved at this point.
}
})
请参阅: