简体   繁体   English

如何在Typescript中编译装饰器(注释)?

[英]How are decorators (annotations) compiled in Typescript?

In Angular 2, I can create a component, like this: 在Angular 2中,我可以创建一个组件,如下所示:

import {Component, Template} from 'angular2/angular2'

@Component({
  selector: 'my-component'
})
@View({
  inline: "<div>Hello my name is {{name}}</div>"
})
export class MyComponent {
  constructor() {
    this.name = 'Max'
  }
  sayMyName() {
    console.log('My name is', this.name)
  }
}

(source: http://blog.ionic.io/angular-2-series-components/ ) (来源: http//blog.ionic.io/angular-2-series-components/

This is then compiled into regular ES5. 然后将其编译为常规ES5。

My question is in 2 parts: 我的问题分为两部分:

  1. These decorators are specific to Angular. 这些装饰器特定于Angular。 How are they defined? 他们是如何定义的?
  2. How do I define my own decorators? 如何定义自己的装饰器?

In fact, you should call "annotations" decorators since it's slighty different ;-) They allow to decorate objects. 实际上,你应该调用“注释”装饰器,因为它略有不同;-)它们允许装饰对象。 This blog post can give some more hints here: http://blog.thoughtram.io/angular/2015/05/03/the-difference-between-annotations-and-decorators.html . 这篇博客文章可以提供更多提示: http//blog.thoughtram.io/angular/2015/05/03/the-difference-between-annotations-and-decorators.html

So decorators aren't something specific to Angular. 所以装饰器不是Angular特有的。 There is a proposal for ES7 and they are also supported by the TypeScript language itself. 有一个针对ES7的提议,它们也受到TypeScript语言本身的支持。 This can be used in conjonction with the reflect-metadata library (it's contained into the angular2-polyfills.js file) to set and get metadata for elements. 这可以与reflect-metadata库(它包含在angular2-polyfills.js文件中)结合使用,以设置和获取元素的元数据。

  • Class decorator 类装饰器

     export function MyClassDecorator(value: string) { return function (target: Function) { Reflect.defineMetadata("MyClassDecorator", value, target); } } @Component({ ... }) @MyClassDecorator("my metadata") export class AppComponent { constructor() { let decoratorValue: string = Reflect.getMetadata("MyClassDecorator", this.constructor); } } 
  • Function decorator 功能装饰器

     export function log(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) { var originalMethod = descriptor.value; descriptor.value = function(...args: any[]) { console.log("The method args are: " + JSON.stringify(args)); var result = originalMethod.apply(this, args); console.log("The return value is: " + result); return result; }; return descriptor; } export class AppComponent { constructor() { } @MyMethodDecorator getMessage() { return 'test'; } } 
  • Parameter decorator 参数装饰器

     export function MyParameterDecorator(param1) { return function(target: any, methodKey: string | symbol, parameterIndex: number) { (...) }; } 
  • Class property decorator 类属性装饰器

     export function MyPropertyDecorator(target: any, propertyKey: string | symbol) { (...) } 

So in general a decorator corresponds to a function. 因此通常装饰器对应于一个功能。 If there is no need to return a wrapping one if you don't use parameter. 如果不使用参数,则无需返回包装。 If you want to use parameters for the decorator you need an additional function to get parameters and return the actualy decorator: 如果你想使用装饰器的参数,你需要一个额外的函数来获取参数并返回实际装饰器:

// In the case of a parameter decorator
// myMethod(@MyDecoratorWithoutParameter someParam) { ... }
export function MyDecoratorWithoutParameter(target: any,
    propertyKey: string | symbol, parameterIndex: number) {
  console.log('decorator called');
}

// myMethod(@MyDecoratorWithParameter('test') someParam) { ... }
export function MyDecoratorWithParameter(param1) {
  // param1 contains 'test'
  return function(target: any, propertyKey: string | symbol,
                  parameterIndex: number) {
    console.log('decorator called');
  };
}

Here is a plunkr corresponding to my samples: https://plnkr.co/edit/0VBthTEuIAsHJjn1WaAX?p=preview . 这是一个与我的样本对应的plunkr: https ://plnkr.co/edit/0VBthTEuIAsHJjn1WaAX?p = preview。

Here are links that could give you more details with TypeScript: 以下链接可以为您提供有关TypeScript的更多详细信息:

Hope it helps you, Thierry 希望它对你有帮助,蒂埃里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM