我做错了什么?我有以下装饰器函数设置来保存关于类的元数据,它们都看起来像这样(一个用于设置数据,另一个用于获取数据):
function setComponentMenu(text: string): any {
return Reflect.metadata('componentPath', text);
}
function getMenuPath(target: any): any {
return Reflect.getMetadata('componentPath', target);
}
然后我就这样使用了它,customEditor
装饰工作得很好,并将CameraEditor
类的实例放入Globals.editors
:
@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);
}
我收到了undefined
,这对于没有@setComponentMenu
但CameraEditor
确实拥有它的项目很好,所以我希望控制台显示{{1} }。
有什么问题?
答案 0 :(得分:1)
类装饰器需要具有以下签名:
function decorator(constructor: Function)
如果要将值传递给它,则需要使用decorator factory:
function setComponentMenu(text: string) {
return (constructor) => {
...
}
}
此外,您不应将class decorator的值返回为:
如果类装饰器返回一个值,它将替换该类 使用提供的构造函数声明。
注意如果您选择返回新的构造函数,则必须 注意保持原始原型。适用的逻辑 运行时的装饰器不会为你做这个。
除非您想要替换构造函数。
我无法使用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");
}