2016-01-21 82 views
10

在角2,我可以創建一個組件,這樣的:如何在Typescript中編譯裝飾器(註釋)?

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) 
    } 
} 

(來源:http://blog.ionic.io/angular-2-series-components/

這然後被編譯成規則ES5。

我的問題是兩個部分:

  1. 這些裝飾是特定於角。他們如何定義?
  2. 如何定義我自己的裝飾器?
+0

請訪問http: //博客。wolksoftware.com/decorators-reflection-javascript-typescript。這個問題也似乎很相似http://stackoverflow.com/questions/34465214/access-meta-annotation-inside-class-typescript/34466523 –

+0

這是一個很好的博客文章。 – superluminary

回答

18

事實上,你應該調用「annotations」裝飾器,因爲它有點不同;-)它們允許裝飾對象。這篇博文可以提供更多的提示:http://blog.thoughtram.io/angular/2015/05/03/the-difference-between-annotations-and-decorators.html

所以裝飾者不是特定於Angular的東西。有一個針對ES7的提議,它們也受到TypeScript語言本身的支持。這可以結合reflect-metadata庫(包含在angular2-polyfills.js文件中)來設置和獲取元素的元數據。

  • 類裝飾

    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); 
        } 
    } 
    
  • 功能裝飾

    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'; 
        } 
    } 
    
  • 參數裝飾

    export function MyParameterDecorator(param1) { 
        return function(target: any, methodKey: string | symbol, 
            parameterIndex: number) { 
        (...) 
        }; 
    } 
    
  • 類屬性裝飾

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

所以一般一個裝飾對應於函數。如果不使用參數,則不需要返回包裝。如果你想使用的參數爲裝飾,你需要一個額外的功能來獲得參數和返回actualy裝飾:

// 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'); 
    }; 
} 

這裏是對應於我的樣本plunkr:https://plnkr.co/edit/0VBthTEuIAsHJjn1WaAX?p=preview

這裏有鏈接,可以給你更多的細節與打字稿:

希望它可以幫助你, 蒂埃裏