2016-08-21 4 views
0

私は間違っていますか?私は、クラスに関するメタデータを保持するために、次のデコレータ機能を設定している、と彼らは両方の(データを取得するためにデータを設定するために1つずつ)のようになります。私は、このようにそれを使用しています反射デコレータがオブジェクトのデータを保存/取得していません

function setComponentMenu(text: string): any { 
    return Reflect.metadata('componentPath', text); 
} 
function getMenuPath(target: any): any { 
    return Reflect.getMetadata('componentPath', target); 
} 

、およびcustomEditorデコレータはうまく動作し、Globals.editorsCameraEditorクラスのインスタンスを置きます:

@customEditor(Camera) 
@setComponentMenu('Renderers/Camera') 
class CameraEditor extends Editor { 

} 

値が設定されている、と私はこのようにそれを取り戻すためにしようとした後:

for(let i = 0; i < Globals.editors.length; i++){ 
    let editor: Editor = Globals.editors[i]; 
    let path = getMenuPath(editor); 
    console.log(path); 
} 

私は@setComponentMenuを持っていないけどCameraEditorが、それはので、私はコンソールがRenderers/Cameraを表示するように期待していないアイテムの罰金である、undefinedを取得しています。

どうしたのですか?

答えて

1

クラスのデコレータは、次のシグネチャを持っている必要があります:

function decorator(constructor: Function) 

あなたはそれに値を渡したい場合は、あなたがdecorator factoryを使用する必要があります。

function setComponentMenu(text: string) { 
    return (constructor) => { 
     ... 
    } 
} 

また、あなたは返すべきではありませんclass decoratorの値:

クラスデコレータが値を返すと、それはc提供コンストラクタ関数と 宣言を小娘。

新しいコンストラクタ関数を返すように選択した場合は、元のプロトタイプを維持するために に注意する必要があります。実行時に デコレータを適用するロジックは、これを行いません。

もちろん、コンストラクタを置き換えたい場合を除きます。

は、私はそれが Reflect.metadataを使用して動作させることができませんでしたが、私は実用的なソリューションが Reflect.defineMetadataを使用して思い付いた:

function setComponentMenu(text: string) { 
    return (constructor) => { 
     Reflect.defineMetadata("componentPath", text, constructor, "class"); 
    } 
} 

function getMenuPath(target: any): any { 
    return Reflect.getMetadata("componentPath", target.constructor, "class"); 
} 

あなたが代わりにコンストラクタのプロトタイプにメタデータ情報を保存することができます。

function setComponentMenu(text: string) { 
    return (constructor) => { 
     Reflect.defineMetadata("componentPath", text, constructor.prototype, "class"); 
    } 
} 

function getMenuPath(target: any): any { 
    return Reflect.getMetadata("componentPath", target.constructor.prototype, "class"); 
} 
+0

ありがとうございます!それはちょうど完全に動作します!私はプロトタイプで2番目の例を使用しましたが、それはトリックです! –

関連する問題