یک نکتهی تکمیلی: بهبود کنترل نمایش و مخفی سازی قسمتهای مختلف
یک روش «نمایش و یا مخفی کردن قسمتهای مختلف صفحه بر اساس نقشهای کاربر وارد شدهی به سیستم» را در مطلب جاری مطالعه کردید. روش دیگر اینکار، تهیهی یک دایرکتیو و سپس اعمال آن به المانهای مختلف صفحه است. به علاوه با توجه به اینکه Auth Service ما رخداد خروج کاربر را نیز گزارش میکند، روش ارائه شدهی در اینجا نیاز به اندکی بهبود هم دارد:
ngOnInit() {
this.isAdmin = this.authService.isAuthUserInRole("Admin");
this.isUser = this.authService.isAuthUserInRole("User");
}
نتیجهی این بررسی، حتی با خروج کاربر نیز تغییری نخواهد کرد و ثابت است. بنابراین بهتر است مشترک this.authService.authStatus شد و نسبت به رخدادهای صادر شدهی توسط سرویس اعتبارسنجی، همانند کامپوننت هدر، واکنش نشان داد.
برای پیاده سازی آن و همچنین کپسوله سازی این عملیات تکراری، دایرکتیو جدیدی را در مسیر src\app\shared\directives\is-visible-for-auth-user.directive.ts ایجاد میکنیم:
import { Directive, ElementRef, Input, OnDestroy, OnInit } from "@angular/core";
import { Subscription } from "rxjs/Subscription";
import { AuthService } from "../../core/services/auth.service";
@Directive({
selector: "[isVisibleForAuthUser]"
})
export class IsVisibleForAuthUserDirective implements OnInit, OnDestroy {
private subscription: Subscription;
@Input() isVisibleForRoles: string[];
constructor(private elem: ElementRef, private authService: AuthService) { }
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
ngOnInit(): void {
this.subscription = this.authService.authStatus$.subscribe(status => this.changeVisibility(status));
this.changeVisibility(this.authService.isAuthUserLoggedIn());
}
private changeVisibility(status: boolean) {
const isInRoles = !this.isVisibleForRoles ? true : this.authService.isAuthUserInRoles(this.isVisibleForRoles);
this.elem.nativeElement.style.display = isInRoles && status ? "" : "none";
}
}
در اینجا علاوه بر بررسی isAuthUserLoggedIn و isAuthUserInRoles، نسبت به تغییرات this.authService.authStatus نیز واکنش نشان داده میشود.
سپس تعریف آنرا به قسمتهای declarations و exports مربوط به SharedModule اضافه میکنیم:
import { IsVisibleForAuthUserDirective } from "./directives/is-visible-for-auth-user.directive";
@NgModule({
declarations: [
IsVisibleForAuthUserDirective
],
exports: [
IsVisibleForAuthUserDirective
]
})
export class SharedModule {}
اکنون ماژول Dashboard برای استفادهی از این امکانات تنها کافی است SharedModule را دریافت کند (یا هر ماژول دیگری نیز به همین ترتیب است):
import { SharedModule } from "../shared/shared.module";
@NgModule({
imports: [
SharedModule
]
})
export class DashboardModule { }
پس از آن برای مخفی سازی یک المان از دید کاربران وارد نشدهی به سیستم، فقط کافی است دایرکتیو isVisibleForAuthUser را به المان اعمال کنیم:
<div class="alert alert-info" isVisibleForAuthUser>
Is-Visible-For-AuthUser
</div>
و یا اگر نیاز به اعمال نقشها نیز وجود داشت میتوان از خاصیت isVisibleForRoles آن استفاده کرد:
<div class="alert alert-success" isVisibleForAuthUser [isVisibleForRoles]="['Admin','User']">
Is-Visible-For-Roles = ['Admin','User']
</div>
خلاصهی این تغییرات به کدهای نهایی این سری اعمال شدهاند.