2016-03-24 7 views
2

を書きます。 この注釈は、特定のコンポーネントにボディクラスを追加する必要があります。私はAngular2プロジェクトでそれを使用するために自分自身の注釈をしようと、今日は自分のAngular2注釈

だから、私は角度のソースコードを検索しましたが、それはどこで、どのように注釈が作成された参照してくださいので、難しいです。

export function BodyClass(classes: any): ClassDecorator{ 
    classes = classes || {}; 

    if(typeof classes === 'string'){ 
     classes = {classes}; 
    } 

    return function changeBodyClass(){ 
     console.log('ici'); 
    } 
} 

そして、私のコンポーネント:

import {Component} from "angular2/core"; 
import {RouterOutlet} from "angular2/router"; 
import {BodyClass} from "../core/annotations/body_class"; 

@Component({ 
    selector: 'my-component', 
    template: ` 
     <router-outlet></router-outlet> 
    `, 
}) 
@BodyClass('test') 
export class MyComponent{ 
} 

注釈で私のコンソールログが正しく解雇が、私は「DOM」を使用したいた瞬間のために

は、私はこれを試してみましたクラスを angular2/src/platform/dom/dom_adapterから私のクラスを追加するが、コンソールログ(それをインスタンス化する必要はありません)では未定義のDOMを使用します。

しかし、DOMクラスは私のコンポーネントに直接適しています。 ngOnInit関数でクラスを追加し、それらをngOnDestroyで削除します。

しかし、私は多くのコンポーネントでこの動作をしたい、と私は新しい注釈が最善の方法だと思います。

たぶん、あなたは、このためのより良いアイデアを持って?アノテーション上のDOMクラスを操作するには?

ありがとうございます!

答えて

0

、コンポーネントインスタンスレベルではなく、コンポーネントクラス1で仕事をしたいので、それはそれほど明白ではありません。したがって、対応するコンストラクタ関数をラップする必要があります。

export function MyComponentDecorator(value: string) { 
    return function (target: Function) { 
    var original = target; 

    function construct(constructor, args) { 
     var c : any = function() { 
     // Call the target constructor 
     var ret = constructor.apply(this, args); 

     // Add your additional processing 

     return ret; 
     } 
     c.prototype = constructor.prototype; 
     return new c(); 
    } 

    // The new constructor 
    // Don't forget to add a name at this function 
    // since Angular requires it for the template compilation 
    var f : any = function WrappedComponent(...args) { 
     return construct(original, args); 
    } 

    f.prototype = original.prototype; 

    return f; 
    } 
} 

この時点で、コンポーネントインスタンスはラップされますが、コンポーネントメタデータは失われます。あなたは手でそれらをコピーする必要があります。

f.prototype = original.prototype; 

var annotations = Reflect.getMetadata('annotations', original)); 
Reflect.defineMetadata('annotations', annotations, f); 

var properties = Reflect.getMetadata('propMetadata', original)); 
Reflect.defineMetadata('propMetadata', properties, f); 

return f; 

は、単に前または後にそれを追加し、このデコレータを使用するには@Component 1:

@MyComponentDecorator() 
@Component({ 
    selector: 'sub', 
    template: ` 
    <div (click)="showMessage()">Test</div> 
    ` 
}) 
export class SubComponent { 
    (...) 
} 

あなたが気づくことができるコンポーネントレベルでこのデコレータはコピーのみメタデータをその他のものはプロパティ(@Input)と同じではありません...

このplunkr:https://plnkr.co/edit/PrAvliIpWTNFAtH33bHA?p=previewを参照してください。

+0

謝辞Thierry。私はあなたの説明をあなたのplunkrをチェックし、私は戻ってきます;) – PallMallShow

関連する問題