2016-08-21 7 views
0

Was mache ich falsch? Ich habe das Setup folgende Dekorateur Funktionen Metadaten über eine Klasse zu halten, und sie beide so aussehen (man die Daten zu setzen und ein um die Daten zu erhalten):Reflect Decorator speichert keine Daten für ein Objekt

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

ich dann wie folgt aus bin, und die customEditor Dekorateur funktioniert gut, und stellt eine Instanz der Klasse CameraEditor in Globals.editors:

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

} 

Nachdem der Wert eingestellt wurde, und ich versuche, es so zu kommen:

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

Ich bekomme undefined, das ist in Ordnung für Elemente, die nicht die @setComponentMenu haben, aber die CameraEditor hat es so, ich würde erwarten, dass die Konsole Renderers/Camera angezeigt wird.

Was ist los?

Antwort

1

Klasse Dekorateure die folgende Signatur haben muss:

function decorator(constructor: Function) 

Wenn Sie es dann müssen passieren Werte wollen Sie eine decorator factory verwenden:

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

Außerdem sollten Sie eine nicht zurück Wert für class decorator wie:

Wenn der Klassendekorator einen Wert zurückgibt, ersetzt er den c lass Deklaration mit der bereitgestellten Konstruktorfunktion.

HINWEIS Sollten Sie eine neue Konstruktorfunktion zurückgegeben haben, müssen Sie darauf achten, dass der ursprüngliche Prototyp beibehalten wird. Die Logik, die Dekoratoren zur Laufzeit gilt, wird dies nicht für Sie tun.

Sofern Sie den Konstruktor natürlich nicht ersetzen möchten.

war ich nicht in der Lage, um es Reflect.metadata mit funktioniert, aber ich kam mit einer Arbeitslösung mit Reflect.defineMetadata up:

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

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

Sie können anstelle des Konstrukteurs die Metadaten Informationen zum Prototyp speichern:

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

Vielen Dank! Das funktioniert einfach perfekt! Ich habe dein zweites Beispiel mit dem Prototyp verwendet, und das macht den Trick! –

Verwandte Themen