In Angular 2, I can create a component, like this:
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/)
This is then compiled into regular ES5.
My question is in 2 parts:
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.
So decorators aren't something specific to Angular. There is a proposal for ES7 and they are also supported by the TypeScript language itself. 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.
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.
Here are links that could give you more details with TypeScript:
Hope it helps you, Thierry
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With