如何从 $stateChangeStart 访问 UI-Router 根状态的“解析"属性? [英] How do I access the 'resolve' property of a UI-Router root state from $stateChangeStart?
问题描述
我正在尝试在我的应用中实施用户身份验证检查和访问检查系统,但是我一直遇到障碍.我想这次我的方法是正确的,但我还有最后一个障碍.
一点背景知识:我尝试将所有代码放入 $rootScope.on($startChangeStart) 中,并且它有效,可怕地......但它有效.路由总是被重定向,但由于后端的身份验证检查,它显示第一个请求页面 1/2 秒,然后每次都显示重定向页面.因此,我尝试通过在 $startChangeStart 函数开始时调用 evt.preventDefault() 来暂停"页面加载,该函数起作用了,但是之后尝试将用户放回原始路由会导致路由器中的无限循环.>
因此,经过更多研究和阅读大量堆栈帖子后,我确定解决:"是进行身份验证检查以确保页面在发生时未加载的正确位置,然后在需要时重定向用户从 $startChangeStart 开始.($state 和 event 在我尝试将它们注入解析函数时总是未定义的)这似乎是获胜的组合.
我的问题:我在我的应用程序中解决了根状态:'main'
这是为了避免代码冗余,但是我无法确定如何从 $stateChangeStart 函数访问根状态的属性,因此无法确定解析结果.toState 是子状态,而 fromState 是前一个状态或带有 '^' 路由的抽象状态...
我是否必须将决心放在每个子状态才能使其工作,或者有没有办法从这一点访问根状态?
基本应用设置:
angular.module('App', ['ui.router', 'ui.bootstrap', 'ui.event', 'AngularGM', 'ngResource']).config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider){$urlRouterProvider.when('/home', '/').什么时候('', '/').when('/注册/乔', '/注册').除此以外('/');$stateProvider.state('main', {网址:'',摘要:真实,templateUrl: 'views/main.html',控制器:'MainCtrl',解决: {checkAccess: ['accountService', function(accountService) {accountService.checkAuth(function(){accountService.checkAccess(函数(访问){返回访问;});});}]}}).state('main.home', {网址:'',摘要:真实,templateUrl: 'views/home.html',控制器:'HomeCtrl'}).state('main.home.index', {网址:'/',templateUrl: 'views/home/index.html'});.run(['$rootScope', '$state', '$stateParams', 'accountService', function ($rootScope, $state, $stateParams) {$rootScope.$state = $state;$rootScope.$stateParams = $stateParams;$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {控制台.dir(toState);控制台.dir(toParams);console.dir(fromState);console.dir(fromParams);如果(!toState.checkAccess.allowed){event.preventDefault();$state.transitionTo(toState.checkAccess.newState);}});}]);
这是两个状态对象上的 console.dir() 调用的输出:
对象名称:main.home.index"templateUrl: "views/home/index.html"网址:/"__proto__:对象目的控制器:PlacesCtrl"名称:main.places.search"templateUrl: "views/places.html"网址:/地点"__proto__:对象
更新
糟糕,忘了说 AngularJS 版本是 v1.2.0-rc.2
$state.current console.dir()
对象摘要:真实姓名: ""网址:^"意见:空__proto__:对象
是的,我相信您可以从 $stateChangeStart
函数访问根状态.
当使用纯 AngularJS 时,我通常使用 current.$$route
例如使用下面的路由
.when('/home', {title:'家',bodyClass: '会议',控制器:'HomeCtrl'})
我可以像这样访问根状态
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {如果(当前.$$路由){$rootScope.title = current.$$route.title;$rootScope.bodyClass = current.$$route.bodyClass;}});
使用 ui-router
它只是有点不同,因为它被称为 $state.current
.您可以访问与您点击的任何路线相关联的所有属性(例如:$state.current.url)
所以在你的代码上你可以有这样的东西
.run(['$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) {$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {console.log($state.current.url);});}]);
I'm trying to implement a user auth check and access check system in my app, however I keep hitting roadblocks. I think I have it the correct way this time but I have one last hurdle.
A little background: I tried putting all of the code into the $rootScope.on($startChangeStart) and it worked, horribly... but it worked. The route was always redirected but due to the auth check on the backend it displayed the first request page for 1/2 a second and then the redirect page every time. Thus I tried 'pausing' page load by calling evt.preventDefault() right at the start of the $startChangeStart function, which worked, but trying to put the user back to the original route afterwards caused an infinite loop in the router.
So after more research and reading a lot of stack posts I'm certain that 'resolve:' is the proper place to put the auth check to ensure the page is not loading while it occurs, and then redirect the user if needed from the $startChangeStart. ($state and event are always undefined in my attempts to inject them into a resolve function) It seems like the winning combination.
My problem: I have the resolve on the root state in my app: 'main'
This was to avoid code redundancy, however I cannot determine how to access the root state's properties, and therefore the resolve result, from the $stateChangeStart function. The toState is the child state, while the fromState is either the previous state or an abstract state with the '^' route...
Do I have to put the resolve on every child state for this to work, or is there a way to access the root state from this point?
Basic app setup:
angular.module('App', ['ui.router', 'ui.bootstrap', 'ui.event', 'AngularGM', 'ngResource'])
.config(['$urlRouterProvider', '$stateProvider', function($urlRouterProvider, $stateProvider){
$urlRouterProvider
.when('/home', '/')
.when('', '/')
.when('/sign-up/joe', '/sign-up')
.otherwise('/');
$stateProvider
.state('main', {
url: '',
abstract: true,
templateUrl: 'views/main.html',
controller: 'MainCtrl',
resolve: {
checkAccess: ['accountService', function(accountService) {
accountService.checkAuth(function(){
accountService.checkAccess(function (access){
return access;
});
});
}]
}
})
.state('main.home', {
url: '',
abstract: true,
templateUrl: 'views/home.html',
controller: 'HomeCtrl'
})
.state('main.home.index', {
url: '/',
templateUrl: 'views/home/index.html'
});
.run(['$rootScope', '$state', '$stateParams', 'accountService', function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
console.dir(toState);
console.dir(toParams);
console.dir(fromState);
console.dir(fromParams);
if (!toState.checkAccess.allowed) {
event.preventDefault();
$state.transitionTo(toState.checkAccess.newState);
}
});
}]);
This is the output from the console.dir() calls on the two state objects:
Object
name: "main.home.index"
templateUrl: "views/home/index.html"
url: "/"
__proto__: Object
Object
controller: "PlacesCtrl"
name: "main.places.search"
templateUrl: "views/places.html"
url: "/places"
__proto__: Object
Update
Oops, forgot to mention AngularJS version is v1.2.0-rc.2
$state.current console.dir()
Object
abstract: true
name: ""
url: "^"
views: null
__proto__: Object
Yes, I believe you can access root state from the $stateChangeStart
function.
When using pure AngularJS I normally use current.$$route
For example, using the following route
.when('/home', {
title:'Home',
bodyClass: 'meetings',
controler: 'HomeCtrl'
})
I can access the root state like so
$rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
if (current.$$route) {
$rootScope.title = current.$$route.title;
$rootScope.bodyClass = current.$$route.bodyClass;
}
});
Using ui-router
it's just a bit different as it's called $state.current
. And you can access all the properties associated to whatever route you hit (e.g: $state.current.url)
So on your code you could have something like this
.run(['$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) {
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
console.log($state.current.url);
});
}]);
这篇关于如何从 $stateChangeStart 访问 UI-Router 根状态的“解析"属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!