用angular开发项目有一段时间了,最近做权限控制方面的优化,在这里总结下,也希望能给刚接触angular的同学提供些参考。
在介绍权限控制之前先要简单的介绍下angular的运行块,运行块是在注入器创建之后被执行的,它是angular应用中第一个被执行的方法,他与main方法的概念很接近,运行块通常用来注册全局的事件监听器,因此我们的权限控制自然要在运行块中实现,关于运行块这里就不做过多的介绍了,我们直接来看权限控制是如何实现的。
实现权限控制可以通过路由控制,angular的路由共有4个事件用来监听路由的状态变化: $routeChangeStart, $routeChangeSuccess, $routeChangeError, $routeUpdate.常用的是前两个,这里也不对这些事件一一做介绍了,简单说一下$routeStartChange 顾名思义,相信大家能猜出来他是表示在路由开始变化的事件。
直接看代码例子:
/** 定义路由 **/
var app = angular.module('myApp', ['ngRoute']);
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/query',{
templateUrl:"template/query.html",
controller:'queryCtrl'
}).
when('/orderForm', {
templateUrl: 'template/order-form.html',
controller: 'orderFormCtrl'
}).
otherwise({
redirectTo: '/query'
});
}]);
app.run(function($rootScope,loginService,cm,$location){
$rootScope.$on('$routeChangeStart', function(evt) {
//需要登陆的页面地址
if ($location.path()=="/orderForm") {
if(是否登录成功){
//阻止默认事件
evt.preventDefault();
//判断登陆代码
var loginState=loginService.getLoginState();
loginState.then(function (data) {
if(!data) {
//跳转到登陆页面
cm.jumpLogin();
}else{
//登陆信息处理完成后跳转到该页面
$location.path("/orderForm");
}
},function(data){
alert(data);
});
}
}
});
}):
上面的方式虽然可以实现权限的控制功能,但我在实际应用中发现route事件依然会在加载控制器之前改变地址栏的路径,这实际上不是很好的用户体验,因此我们考虑有没有其他的方式去实现这一功能,好在angular提供的$location服务能够很好的解决这一问题,同时研究后发现$location才是最适合做登陆类的权限控制,而route事件适合做些loading效果
直接看$location的实现方式:(改变事件名称为$locationChangeStart即可)
$rootScope.$on('$locationChangeStart', function (event) {
//需要登陆的页面地址
if ($location.path()=="/orderForm") {
if(是否登录成功){
//阻止默认事件
evt.preventDefault();
//判断登陆代码
var loginState=loginService.getLoginState();
loginState.then(function (data) {
if(!data) {
//跳转到登陆页面
cm.jumpLogin();
}else{
//登陆信息处理完成后跳转到该页面
$location.path("/orderForm");
}
},function(data){
alert(data);
});
}
}
}
});
简单分析下原因:route实际上是监控location的地址的,事件的触发顺序自然是先location后route事件,因此使用location服务控制权限还可以减少不必要的路由事件操作。