1
我创建了一个角度4指令,以便根据用户的权限显示部分视图。 加载应用程序时会触发指令,但在登录或注销后不会调用它们,导致视图保持不变,但用户权限已更改。会真的提供一些帮助。Angular 4指令不是重新评估
@Directive({
selector: '[accessLevel]'
})
export class AccessLevelDirective {
private levelToPredicateMapper: {[id: string] :() => Observable<boolean>} = {};
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private readonly credantialsStorage: CredantialsStorageService,
private readonly authentication: AuthenticationService) {
this.createAccessLevelToPredicatesMapper();
}
@Input() set accessLevel(level: string) {
if (level == null) {
return;
}
let hasAccessLevelFunc = this.levelToPredicateMapper[level];
if (hasAccessLevelFunc == null) {
this.viewContainer.clear();
return;
}
hasAccessLevelFunc().subscribe(hasAccessLevel => {
this.buildOrDestroyView(hasAccessLevel);
})
}
@Input() set roles(roles: [string]) {
this.authentication.isAuthenticated()
.subscribe(isAuthenticated => {
let isValidArrayWithRoles = roles != null && Array.isArray(roles) && roles.length > 0;
let isUserHasOneOfTheRoles = isAuthenticated &&
this.credantialsStorage.get() &&
isValidArrayWithRoles &&
some(this.credantialsStorage.get().roles , role => roles.indexOf(role) > -1);
this.buildOrDestroyView(isUserHasOneOfTheRoles);
})
}
private buildOrDestroyView(isAuthorized: boolean) {
if (isAuthorized) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
private createAccessLevelToPredicatesMapper() {
this.levelToPredicateMapper['all'] =() => Observable.of(true);
this.levelToPredicateMapper['guest'] =() => this.authentication.isAuthenticated().map(isAuth => !isAuth);
this.levelToPredicateMapper['authenticated'] =() => this.authentication.isAuthenticated()
}
}
<div id="navbar-menu" class="collapse navbar-collapse float-xs-none" [ngbCollapse]="menuHidden">
<div class="navbar-nav">
<a class="nav-item nav-link text-uppercase" routerLink="/login" routerLinkActive="active" *accessLevel="'guest'">
<i class="fa fa-home"></i>
<span translate>Login</span>
</a>
<a class="nav-item nav-link text-uppercase" routerLink="/registration" routerLinkActive="active" *accessLevel="'guest'">
<i class="fa fa-home"></i>
<span translate>Register</span>
</a>
<a class="nav-item nav-link text-uppercase" routerLink="/home" routerLinkActive="active">
<i class="fa fa-home"></i>
<span translate>Home</span>
</a>
<a class="nav-item nav-link text-uppercase" routerLink="/about" routerLinkActive="active">
<i class="fa fa-question-circle"></i>
<span translate>About</span>
</a>
<a class="nav-item nav-link text-uppercase" routerLink="/order/new" routerLinkActive="active">
<i class="fa fa-question-circle"></i>
<span translate>Create Order</span>
</a>
<a class="nav-item nav-link text-uppercase" routerLink="/orders" routerLinkActive="active" *accessLevel="'authenticated'">
<i class="fa fa-question-circle"></i>
<span translate>My Orders</span>
</a>
<ng-template accessLevel [roles]="['admin']">
<a class="nav-item nav-link text-uppercase" routerLink="/admin" routerLinkActive="active">
<i class="fa fa-question-circle"></i>
<span translate>Admin</span>
</a>
</ng-template>
</div>
Milad谢谢你的帮助。我决定按照你的建议使用用户主题,它似乎很好。 有没有一种方法来返回Subject.asObservable与预定义值(如Observable.of)?如果是这样,我可以从authentication.isAuthenticated返回Subject.asObservable()。 –
你不能那样做,但你可以使用BehaviorSubject接受一个初始值 – Milad