Setup for a custom ngIf
directive.
app
L common
L directives
L <name>.directive.ts
import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { Permission } from '@models/user';
import { SessionQuery } from '@store/session/session.query';
@Directive({
selector: '[hasPermissions]' // IMPORTANT same name as set!
})
export class HasPermissionsDirective {
@Input() set hasPermissions(permissions: Permission[]) { // IMPORTANT same name as selector!
const hasUserPermissions = this.sessionQuery.hasUserPermissions(...permissions);
this.updateView(hasUserPermissions);
}
constructor(
private readonly viewContainer: ViewContainerRef,
private readonly template: TemplateRef<any>,
private readonly sessionQuery: SessionQuery
) {}
private updateView(show: boolean): void {
if (show) {
this.viewContainer.createEmbeddedView(this.template);
} else {
this.viewContainer.clear();
}
}
}
import { NgIf } from '@angular/common';
import { ChangeDetectorRef, Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { Permission } from '@models/user';
import { SessionQuery } from '@store/session/session.query';
@Directive({
selector: '[hasPermissions]' // IMPORTANT same name as set!
})
export class HasPermissionsDirective {
private ngIfDirective: NgIf;
@Input() set hasPermissions(permissions: Permission[]) { // IMPORTANT same name as selector!
const hasUserPermissions = this.sessionQuery.hasUserPermissions(...permissions);
this.updateView(hasUserPermissions);
}
constructor(
private template: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private changeDetectorRefs: ChangeDetectorRef,
private readonly sessionQuery: SessionQuery
) {
if (!this.ngIfDirective) {
this.ngIfDirective = new NgIf(this.viewContainer, this.template);
}
}
updateView(show: boolean) {
this.ngIfDirective.ngIf = show;
this.changeDetectorRefs.detectChanges();
}
}
Store - More Info
import { Injectable } from '@angular/core';
import { Query } from '@datorama/akita';
import { Permission } from '@models/user';
import { SessionState, SessionStore } from './session.store';
@Injectable(
{ providedIn: 'root' }
)
export class SessionQuery extends Query<SessionState> {
user$ = this.select((state) => state.user);
get snapshot(): SessionState {
return this.getValue();
}
constructor(protected readonly store: SessionStore) {
super(store);
}
hasUserPermissions(...requestedPermissions: Permission[]): boolean {
const userPermissions = this.snapshot.user.permissions;
return requestedPermission.every((p: Permission) => userPermissions.includes(p));
}
}
<div>
<button *hasPermissions="[Permission.view]">View</button>
<button *hasPermissions="[Permission.view, Permission.edit]">Edit</button>
</div>