bki*_*808 9 reflection metadata decorator typescript
在typescript中,是否可以使用属性装饰器为类设置元数据?请考虑以下代码.类装饰器的"目标"显然与属性装饰器的"目标"不同.我可以从另一个中获得一个吗?
import 'reflect-metadata';
const MY_CLASS_DECORATOR_KEY = 'MyClassDecoratorKey';
const MY_PROPERTY_DECORATOR_KEY = 'MyPropertyDecoratorKey';
export const MyClassDecorator = options => {
return function (target) {
console.log('class target: ' , target);
Reflect.defineMetadata(MY_CLASS_DECORATOR_KEY, options, target);
};
};
export const MyPropertyDecorator = (options): PropertyDecorator => {
return (target, property) => {
console.log('property target: ' , target);
const metadata = Reflect.getMetadata(MY_PROPERTY_DECORATOR_KEY, target) || {};
metadata[property] = options;
Reflect.defineMetadata(MY_PROPERTY_DECORATOR_KEY, metadata, target);
};
};
@MyClassDecorator('my class decorator value')
class MyClass {
@MyPropertyDecorator('first my property decorator value')
myFirstProperty: any;
@MyPropertyDecorator('second my property decorator value')
mySecondProperty: any;
}
console.log('keys: ', Reflect.getMetadataKeys(MyClass));
Run Code Online (Sandbox Code Playgroud)
注意输出:
property target: MyClass {}
property target: MyClass {}
class target: function MyClass() {
}
keys: [ 'MyClassDecoratorKey' ]
Run Code Online (Sandbox Code Playgroud)
如何获取元数据键以显示属性装饰器中的键?
是的,你可以自由地在你的装饰工作中做任何你想做的事情,但是当你发现时,你的问题就在于你正在通过的目标.
基本上,在属性装饰器中,target
参数可以是两件事之一,具体取决于装饰器是用于静态属性还是实例属性:
在静态属性上,该target
属性将是类构造函数.这意味着在静态属性上,目标将与类装饰器完全相同.
但是,在实例属性上,target
参数将是prototype
您创建的类的参数,而不是构造函数.这就是你看到你所看到的行为的原因.对于实例属性,您的元数据不会附加到constructor
类装饰器的情况.
但仍然有希望,因为你可以很容易地获得给定一个原型实例的构造函数,因为它存储在一个名为的属性中constructor
.因此,在您的情况下,您可以通过执行以下操作获得您正在寻找的行为:
export const MyPropertyDecorator = (options): PropertyDecorator => {
return (target, property) => {
var classConstructor = target.constructor;
console.log('property target: ' , classConstructor);
const metadata = Reflect.getMetadata(MY_PROPERTY_DECORATOR_KEY, classConstructor) || {};
metadata[property] = options;
Reflect.defineMetadata(MY_PROPERTY_DECORATOR_KEY, metadata, classConstructor);
};
};
Run Code Online (Sandbox Code Playgroud)
注意:上述更改适用于实例属性,但不适用于静态属性.如果您需要处理这两种类型的属性,则需要添加一些额外的逻辑来确定是否使用target
或target.constructor
归档时间: |
|
查看次数: |
5536 次 |
最近记录: |