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