angular 权限控制 service+ 自定义指令(改写ngIf)
功能说明:权限控制
1. 先创建一个service,用户获取用户信息
2. 然后自定义一个结构指令directive(改写ngIf指令):
传入需要的权限,根据调用service获取的用户信息,判断是否有权限,如果有权限,则显示,无权限,则不显示
创建service:
创建一个函数,返回Observable
import { Injectable } from '@angular/core'; import { AuthService } from './auth.service'; import { ApiAuth } from '../apis'; import { UserInfo } from '../model'; import { Observable} from 'rxjs/Rx';
@ Injectable() export class RoleService { roles : Array< any>; userinfo : UserInfo; getUserTime : number; // 调用接口时,记录一下时间点 expiredTime = 1000 * 60 * 5; // 过期时间
constructor( private authService : AuthService, private apiAuth : ApiAuth) { }
getRoles() : Observable< any> { let userInfo$; const userEmail = this.authService. getUserEmail(); if ( ! this.userinfo || Date. now() > this.getUserTime + this.expiredTime) { userInfo$ = this.apiAuth. getUserInfo(userEmail). map( res => { this.getUserTime = Date. now(); return this.userinfo = res as UserInfo; }) // 请求失败时,抛出异常 . catch( this.handleError); } else { // 创建一个新Observable,不然还会去重新调用接口 userInfo$ = Observable. create( serve => { serve. next( this.userinfo); serve. complete(); }); } // 返回的是 Observable 对象 return userInfo$; }
private handleError( error : any) { const errMsg = (error.message) ? error.message : error.status ? ` ${error.status } - ${error.statusText } ` : 'Server error'; console. error(errMsg); return Observable. throw(errMsg); }
}
自定义directive(改写ngIf)
import { Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef, OnDestroy } from '@angular/core'; import { RoleService } from '../service/role.service'; import { UserInfo } from '../model';@ Directive({ selector: '[appRole]' }) export class RoleDirective implements OnDestroy { private _context : RoleContext = new RoleContext(); private _thenTemplateRef : TemplateRef< RoleContext> | null = null; private _elseTemplateRef : TemplateRef< RoleContext> | null = null; private _thenViewRef : EmbeddedViewRef< RoleContext> | null = null; private _elseViewRef : EmbeddedViewRef< RoleContext> | null = null;
userRoles : Array< string>; isShow : boolean; userInfo$;
constructor( private _viewContainer : ViewContainerRef, templateRef : TemplateRef< RoleContext>, private roleService : RoleService) { this._thenTemplateRef = templateRef; }
@ Input() set appRole( condition : any) { this._context.$implicit = this._context.ngIf = condition; this. testRole( this._context.$implicit, () => { this. _updateView(); }); }
@ Input() set appRoleThen( templateRef : TemplateRef< RoleContext>) { this._thenTemplateRef = templateRef; this._thenViewRef = null; // clear previous view if any. this. testRole( this._context.$implicit, () => { this. _updateView(); }); }
@ Input() set appRoleElse( templateRef : TemplateRef< RoleContext>) { this._elseTemplateRef = templateRef; this._elseViewRef = null; // clear previous view if any. this. testRole( this._context.$implicit, () => { this. _updateView(); }); }
private _updateView() { if ( this.isShow) { if ( ! this._thenViewRef) { this._viewContainer. clear(); this._elseViewRef = null; if ( this._thenTemplateRef) { this._thenViewRef = this._viewContainer. createEmbeddedView( this._thenTemplateRef, this._context); } } } else { if ( ! this._elseViewRef) { this._viewContainer. clear(); this._thenViewRef = null; if ( this._elseTemplateRef) { this._elseViewRef = this._viewContainer. createEmbeddedView( this._elseTemplateRef, this._context); } } } }
private testRole( roles, callback) { this.userInfo$ = this.roleService. getRoles(). subscribe( res => { this.userRoles = res.features; this.isShow = true; roles. forEach( r => { if ( ! this.userRoles. includes(r)) { this.isShow = false; return; } }); return callback(); }, error => { this.isShow = false; return callback(); }); }
ngOnDestroy() { this.userInfo$. unsubscribe(); }
}
export class RoleContext { public $implicit : any = null; public ngIf : any = null; }
分为结构指令和属性指令
TempalteRef & ViewContainerRef 和 ElementRef
结构指令如果返回false会阻断后续操作,会比较好一些当前指令和ngIf的区别:
获取的是权限的一个数组,不是一个true或者false参数
参考文章:
https://segmentfault.com/a/1190000009674089#articleHeader17
https://segmentfault.com/a/1190000009499160
https://segmentfault.com/a/1190000008672478
https://segmentfault.com/a/1190000009307714#articleHeader5
https://segmentfault.com/a/1190000008653690
https://segmentfault.com/a/1190000008626070
https://segmentfault.com/a/1190000008695459
知识点:
angular service
angular directive(结构指令、属性指令)
angular 组件和指令的生命周期 点击打开链接
学习ngIf源码
Rxjs原理
Rxjs的Observable
教程1
教程2
教程3
优化:
使用RxJs改写:
注意事项:
1. 注意处理异常
2. 注意请求的间隔时间
3. 要在自定义组件的生命周期结束之后,销毁流
4. 有数据时,并且在有效期内,不去重新请求
优化之前的代码(这种方式不好,仅作为记录)
service:
import { Injectable } from '@angular/core'; import { AuthService } from './auth.service'; import { ApiAuth } from '../apis'; import { UserInfo } from '../model';@ Injectable() export class RoleService { roles : Array< any>; userinfo : UserInfo;
constructor( private authService : AuthService, private apiAuth : ApiAuth) { }
getRoles( callback) { const userEmail = this.authService. getUserEmail(); this.apiAuth. getUserInfo(userEmail). subscribe( res => { this.userinfo = res as UserInfo; return callback( this.userinfo); }); }
}
directive:
import { Directive, EmbeddedViewRef, Input, TemplateRef, ViewContainerRef } from '@angular/core'; import { RoleService } from '../service/role.service'; import { UserInfo } from '../model';@ Directive({ selector: '[appRole]' }) export class RoleDirective { private _context : RoleContext = new RoleContext(); private _thenTemplateRef : TemplateRef< RoleContext> | null = null; private _elseTemplateRef : TemplateRef< RoleContext> | null = null; private _thenViewRef : EmbeddedViewRef< RoleContext> | null = null; private _elseViewRef : EmbeddedViewRef< RoleContext> | null = null;
userRoles : Array< string>; isShow : boolean;
constructor( private _viewContainer : ViewContainerRef, templateRef : TemplateRef< RoleContext>, private roleService : RoleService) { this._thenTemplateRef = templateRef; }
@ Input() set appRole( condition : any) { this._context.$implicit = this._context.ngIf = condition; this. testRole( this._context.$implicit, () => { this. _updateView(); }); }
@ Input() set appRoleThen( templateRef : TemplateRef< RoleContext>) { this._thenTemplateRef = templateRef; this._thenViewRef = null; // clear previous view if any. this. testRole( this._context.$implicit, () => { this. _updateView(); }); }
@ Input() set appRoleElse( templateRef : TemplateRef< RoleContext>) { this._elseTemplateRef = templateRef; this._elseViewRef = null; // clear previous view if any. this. testRole( this._context.$implicit, () => { this. _updateView(); }); }
private _updateView() { if ( this.isShow) { if ( ! this._thenViewRef) { this._viewContainer. clear(); this._elseViewRef = null; if ( this._thenTemplateRef) { this._thenViewRef = this._viewContainer. createEmbeddedView( this._thenTemplateRef, this._context); } } } else { if ( ! this._elseViewRef) { this._viewContainer. clear(); this._thenViewRef = null; if ( this._elseTemplateRef) { this._elseViewRef = this._viewContainer. createEmbeddedView( this._elseTemplateRef, this._context); } } } }
private testRole( roles, callback) { this.roleService. getRoles(( data : UserInfo) => { this.userRoles = data.features;
this.isShow = true; roles. forEach( r => { if ( ! this.userRoles. includes(r)) { this.isShow = false; return; } }); return callback(); }); }
}
export class RoleContext { public $implicit : any = null; public ngIf : any = null; }
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
