如何在Angular中检索组件的元数据

Mor*_*ing 7 angular-decorator angular2-decorators angular-compiler-cli angular

Angular组件有装饰器:

@Component({ ... })
export class MyAngularComponent {
  @Input() myInputParam: MyType;
  @Input() myOtherInputParam: MyOtherType;
  @Output() myOutputParam: MyOtherOutputType;
}
Run Code Online (Sandbox Code Playgroud)

我有一个Angular库,如果我能以编程方式检索@Input()给定组件类(虽然属于库)中的 Angular的装饰器,可以避免很多代码重复(并减少bundle大小).

但我怀疑这种实现的可移植性.我已经读过某个地方,如果Angular应用程序是在启用了AoT的情况下构建的(并且只使用了Angular装饰器),则不需要Reflect polyfill(在运行时读取装饰器所需).所以我认为我不能只使用Reflect.*.Angular如何存储装饰器?是否有可靠,面向未来的方式来阅读它们?

缩小应该不是问题,因为它只用于读取库组件的装饰器,所以我可以控制它.

所以,如果这是可行的方式(或者不是,我仍然感兴趣),我怎么能读取那些装饰器?

Max*_*kyi 10

我已经读过某个地方,如果在启用AoT的情况下构建了Angular应用程序,则不需要Reflect polyfill(在运行时读取装饰器)... Angular如何存储装饰器?

事实上,Angular计划Reflect运行时删除对象的依赖.出于这个原因,在最新的V5 Reflect.defineMetadata已经被替换为Object.definePropertymakeDecorator其负责的元数据连接到所述类.这是相关代码:

export const ANNOTATIONS = '__annotations__';
export function makeDecorator(
    ...
    const TypeDecorator: TypeDecorator = <TypeDecorator>function TypeDecorator(cls: Type<any>) {
      // Use of Object.defineProperty is important since it creates non-enumerable property which
      // prevents the property is copied during subclassing.
      const annotations = cls.hasOwnProperty(ANNOTATIONS) ?
          (cls as any)[ANNOTATIONS] :
          Object.defineProperty(cls, ANNOTATIONS, {value: []})[ANNOTATIONS]; <-----
      annotations.push(annotationInstance);
      return cls;
    };
Run Code Online (Sandbox Code Playgroud)

这意味着在v5中你可以访问组件类上的装饰器,如下所示:

export class AppComponent {
    constructor() {
        console.log((<any>AppComponent).__annotations__);
    }
Run Code Online (Sandbox Code Playgroud)

是否有可靠,面向未来的方式来阅读它们?我不认为Angular有任何未来的证据.

使用AOT Angular 编译应用程序时,使用静态代码分析并严重依赖TS编译器生成的AST.如果你有兴趣在构建时访问装饰器,我想这是要走的路,我称之为最具前瞻性的解决方案.

  • @MorganTouvereyQuilling我还强烈建议您关注https://blog.angularindepth.com/ publication.在那里,您可以找到有关内部结构的更多信息 (3认同)