功能说明:权限控制
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;
}