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

时间:2017-10-25 16:36:53

标签: angular angular-decorator angular-compiler-cli angular2-decorators

Angular组件有装饰器:

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

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

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

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

所以,如果这种方法可以通过便携方式进行(或者不是,我仍然感兴趣),我该如何阅读这些装饰者?

1 个答案:

答案 0 :(得分:8)

  

我在某处读过Reflect polyfill(需要阅读   如果构建了Angular应用程序,则不需要运行时的装饰器   启用AoT ...... Angular如何存储装饰器?

事实上,Angular计划删除对Reflect对象的依赖,即使在运行时中也是如此。因此,在最新的v5中,Reflect.defineMetadata已替换为负责将元数据附加到类的Object.defineProperty中的makeDecorator。以下是相关代码:

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;
    };

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

export class AppComponent {
    constructor() {
        console.log((<any>AppComponent).__annotations__);
    }
  

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

使用AOT编译应用程序时 Angular使用静态代码分析,并且在很大程度上依赖于TS编译器生成的AST。如果您有兴趣在构建时访问装饰器,我想这是可行的方法,我称之为最具前瞻性的解决方案。