Angular 11 个结构指令在通过 AOT 编译时中断

Angular 11 structural directive breaks when compiling via AOT

我正在尝试从 Angular 8 迁移到 11。

除自定义指令外,我已使所有功能正常运行。当 运行 应用程序使用 ng serve 时,指令 有效 ,但在使用 --aot--prod 旗帜。浏览器控制台日志报如下错误:

core.js:10073 NG0303: Can't bind to 'hasPermission' since it isn't a known property of 'span'.

其中 hasPermission 是指令,span 是我尝试使用该指令的任何元素。这曾经在 Angular 8.

中运行良好

指令本身:

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) {
   ...
  }
}

它是使用 SharedModule 声明和导出的:

@NgModule({
  declarations: [
   ...
   PermissionsDirective,
   ...
  ],
  exports: [
   ...
   PermissionsDirective,
   ...
  ]
})

export class SharedModule {}

最后,它被用在许多其他 modules/components 中,例如:

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' })...

我认为这与 -aot 标志没有将模块放置在正确的位置以使其可见有关?否则我不明白为什么只使用 ng serve

就没有问题

此处显示的最小示例:https://stackblitz.com/edit/angular-ivy-rzu5jm?file=src/app/app.component.html

stackblitz 的浏览器控制台显示相同的错误 (NG0303)

问题出在 @Input('')。你不应该在装饰器中设置任何东西,或者如果你这样做,它需要有相同的名称,如果你想将它命名为别名。删除空字符串应该可以修复它:

@Input()
set hasPermission(value: any) {
  console.log(value);
}

FORKED STACKBLITZ

您必须从装饰器中删除重命名 @Input('') -> @Input()

@Input() 
set hasPermission(value: any) {
  ...
}