Here's how to create a structural directive that conditionally renders elements based on user permissions:
1. Create the Permission Directive
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { AuthService } from './auth.service'; // Your authentication service
@Directive({
selector: '[appHasPermission]'
})
export class HasPermissionDirective {
private hasView = false;
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private authService: AuthService
) {}
@Input() set appHasPermission(permission: string | string[]) {
const hasPermission = this.authService.hasPermission(permission);
if (hasPermission && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (!hasPermission && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
}
2. Implement the Auth Service
import { Injectable } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class AuthService {
private currentUser = {
permissions: ['read', 'edit'] // Example permissions
};
hasPermission(requiredPermission: string | string[]): boolean {
if (!requiredPermission) return true;
const required = Array.isArray(requiredPermission)
? requiredPermission
: [requiredPermission];
return required.every(perm =>
this.currentUser.permissions.includes(perm)
);
}
}
3. Use the Directive in Templates
<!-- Single permission check -->
<div *appHasPermission="'edit'">
Only visible to users with 'edit' permission
</div>
<!-- Multiple permission check (AND logic) -->
<div *appHasPermission="['read', 'edit']">
Visible to users with both 'read' AND 'edit' permissions
</div>