我试图阻止所有ui路由器状态更改,直到我对用户进行身份验证为止:
$rootScope.$on('$stateChangeStart', function (event, next, toParams) { if (!authenticated) { event.preventDefault() //following $timeout is emulating a backend $http.get('/auth/') request $timeout(function() { authenticated = true $state.go(next,toParams) },1000) } })
我拒绝所有状态更改,直到对用户进行身份验证为止,但是如果转到使用该otherwise()配置的无效URL,则会收到一条无限循环并显示一条消息:
otherwise()
Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations: [["fn: $locationWatch; newVal: 7; oldVal: 6"],["fn: $locationWatch; newVal: 8; oldVal: 7"],["fn: $locationWatch; newVal: 9; oldVal: 8"],["fn: $locationWatch; newVal: 10; oldVal: 9"],["fn: $locationWatch; newVal: 11; oldVal: 10"]]
以下是我的SSCCE。服务起来,python -m SimpleHTTPServer 7070去localhost:7070/test.html#/bar看看它在你脸上爆炸。而直接导航到唯一有效的angularjs位置不会爆炸localhost:7070/test.html#/foo:
python -m SimpleHTTPServer 7070
localhost:7070/test.html#/bar
localhost:7070/test.html#/foo
<!doctype html> <head> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script> </head> <body ng-app="clientApp"> <div ui-view="" ></div> <script> var app = angular.module('clientApp', ['ui.router']) var myRouteProvider = [ '$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) { $urlRouterProvider.otherwise('/foo'); $stateProvider.state('/foo', { url: '/foo', template: '<div>In Foo now</div>', reloadOnSearch: false }) }] app.config(myRouteProvider) var authenticated = false app.run([ '$rootScope', '$log','$state','$timeout', function ($rootScope, $log, $state, $timeout) { $rootScope.$on('$stateChangeStart', function (event, next, toParams) { if (!authenticated) { event.preventDefault() //following $timeout is emulating a backend $http.get('/auth/') request $timeout(function() { authenticated = true $state.go(next,toParams) },1000) } }) } ]) </script> </body> </html>
我是否应该使用另一种方法来完成此身份验证阻止?我确实意识到此身份验证阻止仅在客户端。在此示例中,我没有显示服务器端的内容。
欺骗。这是$urlRouterProvider 和之间的交互问题$stateProvider。我不应该用$urlRouterProvider我的otherwise。我应该使用类似的东西:
$urlRouterProvider
$stateProvider
otherwise
$stateProvider.state("otherwise", { url: "*path", template: "Invalid Location", controller: [ '$timeout','$state', function($timeout, $state ) { $timeout(function() { $state.go('/foo') },2000) }] });
甚至是透明的重定向:
$stateProvider.state("otherwise", { url: "*path", template: "", controller: [ '$state', function($state) { $state.go('/foo') }] });
现在总共:
<!doctype html> <head> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.js"></script> <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script> </head> <body ng-app="clientApp"> <div ui-view="" ></div> <script> var app = angular.module('clientApp', ['ui.router']) var myRouteProvider = [ '$stateProvider', function($stateProvider) { $stateProvider.state('/foo', { url: '/foo', template: '<div>In Foo now</div>', reloadOnSearch: false }) $stateProvider.state("otherwise", { url: "*path", template: "", controller: [ '$state', function($state) { $state.go('/foo') }] }); }] app.config(myRouteProvider) var authenticated = false app.run([ '$rootScope', '$log','$state','$timeout', function ($rootScope, $log, $state, $timeout) { $rootScope.$on('$stateChangeStart', function (event, next, toParams) { if (!authenticated) { event.preventDefault() //following $timeout is emulating a backend $http.get('/auth/') request $timeout(function() { authenticated = true $state.go(next,toParams) },1000) } }) } ]) </script> </body> </html>