I am attempting to migrate from Angular 8 to 11.
I have gotten everything to work except for a custom directive. The directive works when running the app using ng serve
, but breaks when compiled with the --aot
or --prod
flags. The browser console log reports the following error:
core.js:10073 NG0303: Can't bind to 'hasPermission' since it isn't a known property of 'span'.
where hasPermission
is the directive, and span
is any element I attempt to use the directive. This used to work fine in Angular 8.
The directive itself:
import { Directive, OnInit, Input, ElementRef, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[hasPermission]',
})
export class PermissionsDirective implements OnInit {
constructor(
private element: ElementRef,
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
) {}
ngOnInit() {
...
}
// this is the structural call we're looking for
// the directive will respond to *hasPermission="'perm'"
@Input('')
set hasPermission(value: any) {
...
}
}
it is declared and exported using a SharedModule:
@NgModule({
declarations: [
...
PermissionsDirective,
...
],
exports: [
...
PermissionsDirective,
...
]
})
export class SharedModule {}
and finally, it's used in many other modules/components like so:
some.module.ts
import { SharedModule } from 'path/shared.module';
@NgModule({
imports: [
SharedModule,
],
declarations: [
SomeComponent
]
})
somehtml.html
...
<div *hasPermission="'somepermission'">...</div>
...
some.component.ts
@Component({ templateUrl: 'somehtml.html' })...
I'm thinking this has something to do with the -aot flag not placing modules in the right place so that they're visible? Otherwise I don't understand why there are no issues using just ng serve
Minimal example shown here: https://stackblitz.com/edit/angular-ivy-rzu5jm?file=src/app/app.component.html
Browser console for the stackblitz shows the same error (NG0303)
CodePudding user response:
The issue is with @Input('')
. You should not set anything inside the decorator, or if you do it needs to have the same name, that if you want to name it as an alias. Removing the empty string should fix it:
@Input()
set hasPermission(value: any) {
console.log(value);
}
CodePudding user response:
You must remove the rename from the decorator @Input('') -> @Input()
@Input()
set hasPermission(value: any) {
...
}