何时以及如何将装饰器应用于@angular包中的装饰类
|
如果我在我的类中使用装饰器,则在导入类时会评估装饰器.这是一个小例子:
@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;
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- angularjs – 将父指令属性传递给子指令属性
- 如何循序渐进向DotNet架构师发展
- Docker pull无法在127.0.1.1:53上查找index.docker.io(无法
- OS / 2 grep有一个很棒的功能,它会在找到搜索项之前显示n行
- angularjs – 如何获取自定义指令内的评估属性
- angularjs – NgUpgrade:升级Angular1组件时无法使用templ
- 基本的AngularJS NVD3指令不起作用,也没有错误
- 带你走进EJB--将EJB发布为Webservice(4)
- scala – 在intellij 2016中通过rest api打开文件
- Scala:如何组合来自不同对象的解析器组合器
