@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包中的装饰类,它不能以这种方式工作.
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;
原文地址:https://www.jb51.cc/angularjs/142510.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。