我正在制作一个编辑器,它将查看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
}
});
我遇到的问题是它会让我设置其他描述符值,但我无法访问它们。
我该怎么做才能做到这一点?
答案 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
}
});