设置有关属性的信息

时间:2016-08-10 19:27:25

标签: javascript typescript ecmascript-6

我正在制作一个编辑器,它将查看javascript类(es6),并显示有关键属性的特定信息。我想尝试使用装饰器来完成这个,所以像这样:

class Transform extends Component {

    @serializable
    public position: Vector3 = Vector3.zero;

}

然后我的装饰师会看起来像这样:

function serializable(...args): any {
    let target = args[0];
    let key = args[1];
    let descriptor = args[2] || {};
    descriptor.writable = true;
    descriptor.serializable = true;
    return descriptor;
}

然后当我分析课程时,我会做这样的事情:

components.forEach(comp => {
    var info = Object.getOwnPropertyDescriptor(comp, 'position');
    if(info.serializable){
        // display in editor
    }
});

我遇到的问题是它会让我设置其他描述符值,但我无法访问它们。

我该怎么做才能做到这一点?

1 个答案:

答案 0 :(得分:1)

我必须承认,from the documentation并不是很清楚,因为它声明:

  

注意不提供属性描述符作为参数   由于如何初始化属性装饰器,属性装饰器   打字稿。这是因为目前没有机制   在定义原型的成员时描述实例属性,   并且无法观察或修改属性的初始值设定项。如   这样,属性装饰器只能用于观察属性   已为某个类声明了特定名称

但是:

  

如果属性装饰器返回一个值,它将被用作   会员的财产描述

所以我的理解是,虽然函数没有让描述符改变,但它可以通过像你那样返回描述符来“改变它”。
但我想这并非如此,因为它不起作用。

然而,就在下面,它给出了如何使用reflect-metadata

执行此操作的示例
import "reflect-metadata";

const serializableMetadataKey = "serializable";

function serializable(): any {
    return Reflect.metadata(serializableMetadataKey, true);
}

function isSerializable(target: any, propertyKey: string) {
    return Reflect.getMetadata(serializableMetadataKey, target, propertyKey);
}

class Transform extends Component {
    @serializable()
    public position: Vector3 = Vector3.zero;
}

components.forEach(comp => {
    if (isSerializable(comp, "position")) {
        // display in editor
    }
});