Custom Structural Directive in Angular for User Roles
Example code for a custom structural directive in angular which acts similar to *ngIf
but can be customised to fit your business logic like user roles or permissions or other cases where the same logic is repeated using *ngIf
and makes it hard to change the logic later.
This can be adapted to creating structural directives like *appIfUserIsAdmin
,*appIfFocusMode
, *appIfFullScreen
or other custom logics and keeps those logic out of your templates.
This example can be used just like *ngIf
:
<mat-card *appIfUserRoleIs="'role-a'"
>Contnet that can be seen by Role A</mat-card
>
<mat-card *appIfUserRoleIs="'role-b'"
>Contnet that can be seen by Role B</mat-card
>
<mat-card *appIfUserRoleIs="'role-c'"
>Contnet that can be seen by Role C</mat-card
>
GitHub link: github.com/sabithpocker/angular-custum-stru..
Complete Code
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { UserService } from './user.service';
@Directive({
selector: '[appIfUserRoleIs]'
})
export class IfUserRoleIsDirective {
private hasView = false;
private currentUserRole: string;
private showForUserRole: string;
constructor(
private userService: UserService,
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef) {
this.userService.getUserRole().subscribe(role => {
this.currentUserRole = role;
this.updateView();
});
}
@Input() set appIfUserRoleIs(role: string) {
this.showForUserRole = role;
this.updateView();
}
updateView() {
const canView = this.canView(this.currentUserRole, this.showForUserRole)
this.hasView = this.renderView(canView, this.hasView)
}
canView(currentRole: string, showForUserRole: string): boolean {
return currentRole === showForUserRole;
}
renderView(show: boolean, hasView: boolean) {
if (show && !hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
hasView = true;
} else if (!show && hasView) {
this.viewContainer.clear();
hasView = false;
}
return hasView;
}
}