Estoy intentando migrar de Angular 8 a 11.
He conseguido que todo funcione excepto una directiva personalizada. La directiva funciona cuando se ejecuta la aplicación usando ng serve , pero se interrumpe cuando se compila con las --aot o --prod . El registro de la consola del navegador informa el siguiente error:
core.js:10073 NG0303: Can't bind to 'hasPermission' since it isn't a known property of 'span'. donde hasPermission es la directiva y span es cualquier elemento que intento usar la directiva. Esto solía funcionar bien en Angular 8.
La propia directiva:
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) { ... } }se declara y exporta usando un SharedModule:
@NgModule({ declarations: [ ... PermissionsDirective, ... ], exports: [ ... PermissionsDirective, ... ] }) export class SharedModule {}y finalmente, se usa en muchos otros módulos/componentes así:
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' })... Estoy pensando que esto tiene algo que ver con el indicador -aot que no coloca los módulos en el lugar correcto para que sean visibles. De lo contrario, no entiendo por qué no hay problemas al usar solo ng serve
Ejemplo mínimo que se muestra aquí: https://stackblitz.com/edit/angular-ivy-rzu5jm?file=src/app/app.component.html
La consola del navegador para stackblitz muestra el mismo error (NG0303)
El problema es con @Input('') . No debes poner nada dentro del decorador, o si lo haces debe tener el mismo nombre, eso si quieres ponerle un alias. Eliminar la cadena vacía debería solucionarlo:
@Input() set hasPermission(value: any) { console.log(value); }Debe eliminar el cambio de nombre del decorador @Input('') -> @Input()
@Input() set hasPermission(value: any) { ... }