So I have a custom ngIf directive that I'm using to handle user authorization, but now I want to make one for certain roles so that I don't have to keep providing them.
Essentially I want to turn this:
<div *appHasAnyRole="['EDIT_USER']; else viewUserTemplateRef">
into something like this:
<div *appIsEditUser="else viewUserTemplateRef">
However, since the directive already knows what role it's looking for, I don't need to provide it a conditional input, so I can't do this in the usual way of:
@Directive({
selector: '[appHasAnyRole]'
})
export class HasAnyRoleDirective {
@Input()
appHasAnyRole(roles: string[]) { ... }
@Input()
appHasAnyRoleElse(templateRef: TemplateRef<NgIfContext> | null) { ... }
}
But, trying something like this also isn't working either.
<div *isEditUser [else]="viewUserTemplateRef">
@Directive({
selector: '[appIsEditUser]'
})
export class IsEditUserDirective {
@Input()
else(templateRef: TemplateRef<NgIfContext> | null) { ... }
}
It throws the 'ol "Can't bind to 'appElse' since it isn't a known property of 'div'." error at runtime.
The closest I've been able to do was leave both inputs as is, and just ignore the conditional input in the directive code, so it looks something like this in the template:
<div appIsEditUser="''; else viewUserTemplateRef">
I'd prefer not to have to do that. Is there another way I'm missing to bind to fields of a directive without using the "default" (named after directive) @Input() ??
You need to wrap it around ng-tempalte, so input works
<ng-template appIsEditUser [else]="viewUserTemplateRef">
@Directive({
selector: '[appIsEditUser]',
})
export class IsEditUserDirective {
@Input()
else(templateRef: TemplateRef<NgIfContext> | null) {
// handle you else here
console.log(templateRef);
}
}
or remove role property completely
<div *appIsEditUser="viewUserTemplateRef"></div>
<ng-template #viewUserTemplateRef >It will be rendered as fallback</ng-template>
@Directive({
selector: '[appIsEditUser]',
})
export class IsEditUserDirective {
@Input()
appIsEditUser(templateRef: TemplateRef<NgIfContext> | null) {
// handle you else here
console.log(templateRef);
}
}
I found a way to do it following https://angular.io/guide/structural-directives#shorthand-examples Here is a stackblitz https://stackblitz.com/edit/angular-empty-project-zfbnfg?file=app/app.component.html
Basically, you need to create an empty context variable for that, so the syntax is valid. You can populate it with any useful value you want.
<div *appIsEditUser="let context else viewUserTemplateRef"></div>
<ng-template #viewUserTemplateRef>It will be rendered as fallback</ng-template>
@Directive({
selector: '[appIsEditUser]',
})
export class IsEditUserDirective {
@Input()
appIsEditUserElse(templateRef: TemplateRef<NgIfContext> | null) {
// handle you else here
console.log(templateRef);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With