加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-17 07:36:01 所属栏目:安全 来源:网络整理
导读:如果我在我的类中使用装饰器,则在导入类时会评估装饰器.这是一个小例子: @NgModule({ ... })export class BModule { ... } 透露为: var BModule = (function () { function BModule() { } BModule = __decorate([ ---------- decorators are applied here
如果我在我的类中使用装饰器,则在导入类时会评估装饰器.这是一个小例子:
@NgModule({ ... })
export class BModule { ... }

透露为:

var BModule = (function () {
    function BModule() {
    }
    BModule = __decorate([  <---------- decorators are applied here
        core_1.NgModule({...})
    ],BModule);
    return BModule;
}());
exports.BModule = BModule;

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

var HttpClientModule = (function () {
    function HttpClientModule() {
    }
    return HttpClientModule;
}());
HttpClientModule.decorators = [
    { type: _angular_core.NgModule,args: [{ ... },] },];

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

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

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

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

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

1)直接API

// Prefer the direct API.
if ((<any>typeOrFunc).annotations && (<any>typeOrFunc).annotations !== parentCtor.annotations) {
  let annotations = (<any>typeOrFunc).annotations;
  if (typeof annotations === 'function' && annotations.annotations) {
    annotations = annotations.annotations;
  }
  return annotations;
}

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

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

2)tsickle的API

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

这种方式角度从@ 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

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

3)使用反射

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

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

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

declare let Reflect: any;
function getAnnotations(typeOrFunc: Type<any>): any[]|null {
  // Prefer the direct API.
  if ((<any>typeOrFunc).annotations) {
    let annotations = (<any>typeOrFunc).annotations;
    if (typeof annotations === 'function' && annotations.annotations) {
      annotations = annotations.annotations;
    }
    return annotations;
  }

  // API of tsickle for lowering decorators to properties on the class.
  if ((<any>typeOrFunc).decorators) {
    return convertTsickleDecoratorIntoMetadata((<any>typeOrFunc).decorators);
  }

  // API for metadata created by invoking the decorators.
  if (Reflect && Reflect.getOwnMetadata) {
    return Reflect.getOwnMetadata('annotations',typeOrFunc);
  }
  return null;
}

function convertTsickleDecoratorIntoMetadata(decoratorInvocations: any[]): any[] {
  if (!decoratorInvocations) {
    return [];
  }
  return decoratorInvocations.map(decoratorInvocation => {
    const decoratorType = decoratorInvocation.type;
    const annotationCls = decoratorType.annotationCls;
    const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
    return new annotationCls(...annotationArgs);
  });
}


const annotations = getAnnotations(AppModule);

更新:

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

const ANNOTATIONS = '__annotations__';

// API for metadata created by invoking the decorators.

if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
   return (typeOrFunc as any)[ANNOTATIONS];
}
return null;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读