如何在Angular中检索组件的元数据 [英] How to retrieve a component's metadata in Angular

查看:174
本文介绍了如何在Angular中检索组件的元数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Angular组件具有装饰器:

An Angular component has decorators:

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

我有一个Angular库,如果我可以在给定的组件类(属于该库,虽然).

I've got an Angular library where a lot of code repetitions could be avoided (and bundle size reduced) if I could programmatically retrieve Angular's @Input() decorators inside a given component class (that belongs to the library, though).

但是我对这种实现的可移植性感到怀疑.我已经读到某个地方,如果Angular应用是在启用了AoT的情况下构建的(并且仅使用了Angular装饰器),则不需要Reflect polyfill(在运行时需要读取装饰器).因此,我想我不能只使用Reflect.*. Angular如何存储装饰器?有可靠的,面向未来的阅读方式吗?

But I have doubts on the portability of such an implementation. I've read somewhere that the Reflect polyfill (needed to read decorators at runtime) isn't needed if the Angular app has been built with AoT enabled (and given that only Angular decorators are used). So I presume I can't just use Reflect.*. How does Angular stores the decorators? Is there a reliable, future-proof way to read them?

缩小不应该是一个问题,因为它将仅用于读取库组件的装饰器,因此我对此有控制权.

Minification shouldn't be a problem since that would be used to read decorators of library's components only, so I have control on this.

因此,如果可以通过便携式方式来实现(或者不能,否则我还是有兴趣),我该如何阅读这些装饰器?

So, if that's doable in a portable way (or not, I'm still interested otherwise), how can I read those decorators?

推荐答案

我在某处阅读了Reflect polyfill(需要阅读 如果已构建Angular应用,则无需在运行时添加装饰器) 启用AoT ... Angular如何存储装饰器?

I've read somewhere that the Reflect polyfill (needed to read decorators at runtime) isn't needed if the Angular app has been built with AoT enabled... How does Angular stores the decorators?

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

In fact, Angular plans to remove dependency on the Reflect object even in runtime. For that reason, in the newest v5 the Reflect.defineMetadata has been replaced with Object.defineProperty in the makeDecorator that is responsible for attaching the metadata to the class. Here is the relevant code:

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中,您可以像这样访问组件类上的装饰器:

It means that in the v5 you can access decorators on the component class like this:

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

是否有可靠的,面向未来的阅读方式? 我认为Angular不能满足未来需求.

Is there a reliable, future-proof way to read them? I don't think there's anything future-proof with Angular.

使用AOT 编译应用程序时,Angular使用静态代码分析,并严重依赖于TS编译器产生的AST.如果您有兴趣在构建时访问装饰器,我想这是一种方法,我将其称为最可靠的解决方案.

When compiling an application using AOT Angular uses static code analysis and heavily relies on the AST produced by the TS compiler. If you're interested in accessing decorators in the build time I guess that is the way to go and I would call it the most future-proof solution.

这篇关于如何在Angular中检索组件的元数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆