javascript - 反射装饰器不保存/检索对象的数据

标签 javascript typescript

我做错了什么?我设置了以下装饰器函数来保存有关类的元数据,它们看起来都是这样的(一个用于设置数据,一个用于获取数据):

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

我得到了未定义,这对于没有@setComponentMenuCameraEditor有它的项目来说很好,所以我期望控制台显示Renderers/Camera

出了什么问题?

最佳答案

类装饰器需要具有以下签名:

function decorator(constructor: Function)

如果你想向它传递值,那么你需要使用 decorator factory :

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

此外,您不应该为 class decorator 返回值如:

If the class decorator returns a value, it will replace the class declaration with the provided constructor function.

NOTE Should you chose to return a new constructor function, you must take care to maintain the original prototype. The logic that applies decorators at runtime will not do this for you.

当然除非你想替换构造函数。

我无法使用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");
}

您可以将元数据信息保存到原型(prototype)而不是构造函数中:

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

关于javascript - 反射装饰器不保存/检索对象的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39066616/

相关文章:

javascript - 使用 JavaScript 搜索文本

javascript - 类型错误 : Cannot read property of undefined using React

javascript - 如何获取 select 元素内的 span 元素的 id?

json - 将 Typescript 类转换为字符串,使用 getter 和 setter 而不是私有(private)变量

javascript - 动态改变rxjs中可观察对象的延迟时间

javascript - 从字符串动态创建 Javascript 对象并将对象作为函数的参数

javascript - lite-uploader 无法处理多个文件

javascript - 在 Typescript 中使用 `: Interface` 和 `as Interface` 有什么区别?

angular - 为什么 TypeScript 在实现时允许重复组件?

angular - 如何在 Angular 中使用 mergeWith 与主题