我正在为编写处理程序$stateChangeStart:
$stateChangeStart
var stateChangeStartHandler = function(e, toState, toParams, fromState, fromParams) { if (toState.includes('internal') && !$cookies.MySession) { e.preventDefault(); // Some login stuff. } }; $rootScope.$on('$stateChangeStart', stateChangeStartHandler);
toState没有include方法。我应该做些不同的事情,还是有办法做我想做的事情?
toState
另外,当//一些登录内容包含时$state.go(...),我会遇到无限循环。是什么原因造成的?
$state.go(...)
这是一个更完整的示例,展示了我们最终要进行的工作:
angular.module('test', ['ui.router', 'ngCookies']) .config(['$stateProvider', '$cookiesProvider', function($stateProvider, $cookiesProvider) { $stateProvider .state('public', { abstract: true }) .state('public.login', { url: '/login' }) .state('tool', { abstract: true }) .state('tool.suggestions', { url: '/suggestions' }); }]) .run(['$state', '$cookies', '$rootScope', function($state, $cookies, $rootScope) { $rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) { if (toState.name.indexOf('tool') > -1 && !$cookies.Session) { // If logged out and transitioning to a logged in page: e.preventDefault(); $state.go('public.login'); } else if (toState.name.indexOf('public') > -1 && $cookies.Session) { // If logged in and transitioning to a logged out page: e.preventDefault(); $state.go('tool.suggestions'); }; }); });
我不喜欢indexOf在中搜索特定状态toState。感觉很幼稚。我不确定为什么toState并且fromState不能成为该$state服务的实例,或者为什么该$state服务不能在其方法中接受状态配置覆盖。
indexOf
fromState
$state
无限循环是由我们方面的错误引起的。我不喜欢这个,所以我还在寻找更好的答案。
当您$stateProvider.state向该对象添加对象时,状态会被传递。因此,您可以添加其他属性,以便以后在需要时阅读。
$stateProvider.state
路由配置示例
$stateProvider .state('public', { abstract: true, module: 'public' }) .state('public.login', { url: '/login', module: 'public' }) .state('tool', { abstract: true, module: 'private' }) .state('tool.suggestions', { url: '/suggestions', module: 'private' });
该$stateChangeStart事件使您可以访问toState和fromState对象。这些状态对象将包含配置属性。
检查自定义模块属性的示例
$rootScope.$on('$stateChangeStart', function(e, toState, toParams, fromState, fromParams) { if (toState.module === 'private' && !$cookies.Session) { // If logged out and transitioning to a logged in page: e.preventDefault(); $state.go('public.login'); } else if (toState.module === 'public' && $cookies.Session) { // If logged in and transitioning to a logged out page: e.preventDefault(); $state.go('tool.suggestions'); }; });
我没有更改Cookie的逻辑,因为我认为这超出了您的问题。
您可以创建一个帮助程序,以使它更加模块化。
值publicStates
publicStates
myApp.value('publicStates', function(){ return { module: 'public', routes: [{ name: 'login', config: { url: '/login' } }] }; });
值privateStates
privateStates
myApp.value('privateStates', function(){ return { module: 'private', routes: [{ name: 'suggestions', config: { url: '/suggestions' } }] }; });
帮手
myApp.provider('stateshelperConfig', function () { this.config = { // These are the properties we need to set // $stateProvider: undefined process: function (stateConfigs){ var module = stateConfigs.module; $stateProvider = this.$stateProvider; $stateProvider.state(module, { abstract: true, module: module }); angular.forEach(stateConfigs, function (route){ route.config.module = module; $stateProvider.state(module + route.name, route.config); }); } }; this.$get = function () { return { config: this.config }; }; });
现在,您可以使用助手将状态配置添加到您的状态配置中。
myApp.config(['$stateProvider', '$urlRouterProvider', 'stateshelperConfigProvider', 'publicStates', 'privateStates', function ($stateProvider, $urlRouterProvider, helper, publicStates, privateStates) { helper.config.$stateProvider = $stateProvider; helper.process(publicStates); helper.process(privateStates); }]);
这样,您可以抽象出重复的代码,并提出一个更具模块化的解决方案。
注意:以上代码未经测试