何时以及如何将装饰器应用于@angular包中的装饰类

前端之家收集整理的这篇文章主要介绍了何时以及如何将装饰器应用于@angular包中的装饰类前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如果我在我的类中使用装饰器,则在导入类时会评估装饰器.这是一个小例子:
  1. @NgModule({ ... })
  2. export class BModule { ... }

透露为:

  1. var BModule = (function () {
  2. function BModule() {
  3. }
  4. BModule = __decorate([ <---------- decorators are applied here
  5. core_1.NgModule({...})
  6. ],BModule);
  7. return BModule;
  8. }());
  9. exports.BModule = BModule;

但是,当模块或任何其他装饰器应用于@angular包时,输出如下:

  1. var HttpClientModule = (function () {
  2. function HttpClientModule() {
  3. }
  4. return HttpClientModule;
  5. }());
  6. HttpClientModule.decorators = [
  7. { type: _angular_core.NgModule,args: [{ ... },] },];

如您所见,装饰器不适用于此处.它们只保存在decorators属性中.为什么它与我的代码不同?

我问的原因是,在导入我的装饰类时,我希望它应用了装饰器,因此使用Reflect是可能的:

  1. const providers = Reflect.getOwnMetadata('annotations',BModule);

但是,对于@angular包中的装饰类,它不能以这种方式工作.

当angulat解析注释时,它有 three options

1)直接API

  1. // Prefer the direct API.
  2. if ((<any>typeOrFunc).annotations && (<any>typeOrFunc).annotations !== parentCtor.annotations) {
  3. let annotations = (<any>typeOrFunc).annotations;
  4. if (typeof annotations === 'function' && annotations.annotations) {
  5. annotations = annotations.annotations;
  6. }
  7. return annotations;
  8. }

我们通常在ES5中编写代码时使用此API

  1. MyComponent.annotations = [
  2. new ng.Component({...})
  3. ]

2)tsickle的API

  1. // API of tsickle for lowering decorators to properties on the class.
  2. if ((<any>typeOrFunc).decorators && (<any>typeOrFunc).decorators !== parentCtor.decorators) {
  3. return convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators);
  4. }

这种方式角度从@ angular /(core | material …)库中读取注释. Angular以这种方式编译库,因为它有助于优化bundle.例如,我们不需要像_decorate,__ Metadata一样运送装饰器助手,代码将更快地执行.

对于该角度使用tslib在构建库时通过使用–importHelpers选项https://github.com/angular/angular/blob/master/build.sh#L127运行tsc.

角度材料做同样的事情https://github.com/angular/material2/blob/master/tools/package-tools/rollup-helpers.ts#L9-L11

  1. // Import tslib rather than having TypeScript output its helpers multiple times.
  2. // See https://github.com/Microsoft/tslib
  3. 'tslib': 'tslib',

3)使用反射

  1. // API for Metadata created by invoking the decorators.
  2. if (this._reflect && this._reflect.getOwnMetadata) {
  3. return this._reflect.getOwnMetadata('annotations',typeOrFunc);
  4. }

当我们使用typescript发出的元数据时使用此API

为确保您能正确获取元数据,您可以考虑使用以下函数

  1. declare let Reflect: any;
  2. function getAnnotations(typeOrFunc: Type<any>): any[]|null {
  3. // Prefer the direct API.
  4. if ((<any>typeOrFunc).annotations) {
  5. let annotations = (<any>typeOrFunc).annotations;
  6. if (typeof annotations === 'function' && annotations.annotations) {
  7. annotations = annotations.annotations;
  8. }
  9. return annotations;
  10. }
  11.  
  12. // API of tsickle for lowering decorators to properties on the class.
  13. if ((<any>typeOrFunc).decorators) {
  14. return convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators);
  15. }
  16.  
  17. // API for Metadata created by invoking the decorators.
  18. if (Reflect && Reflect.getOwnMetadata) {
  19. return Reflect.getOwnMetadata('annotations',typeOrFunc);
  20. }
  21. return null;
  22. }
  23.  
  24. function convertTsickleDecoratorIntoMetadata(decoratorInvocations: any[]): any[] {
  25. if (!decoratorInvocations) {
  26. return [];
  27. }
  28. return decoratorInvocations.map(decoratorInvocation => {
  29. const decoratorType = decoratorInvocation.type;
  30. const annotationCls = decoratorType.annotationCls;
  31. const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
  32. return new annotationCls(...annotationArgs);
  33. });
  34. }
  35.  
  36.  
  37. const annotations = getAnnotations(AppModule);

更新:

通过调用装饰器创建的元数据的API在5.0.0-beta.4中已更改

  1. const ANNOTATIONS = '__annotations__';
  2.  
  3. // API for Metadata created by invoking the decorators.
  4.  
  5. if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
  6. return (typeOrFunc as any)[ANNOTATIONS];
  7. }
  8. return null;

猜你在找的Angularjs相关文章