Typescript 装饰器和 this 上下文
Typescript decorator and this context
我按以下方式在 typescript/angular 中使用装饰器
export function Field({source}){
return (target, property) => {
// Some code here
}
}
那我想这样用
export class MyClass {
constructor(private myService: MyService) {}
@Field({source: () => this.myFn()})
myProp: string;
private myFn() {
// another code
return this.myService.get()
}
}
显然上下文是错误的,"this" 没有引用 MyClass 的实例。
link 使用 MyClass 实例的上下文的最佳方法是什么?
您可以使用迂回方法访问装饰器中的实例,具体取决于您要执行的操作。在下面的示例中,每次设置 属性 时都会调用传递给装饰器的函数。
装饰器将适用于属性和字段。如果一个字段正在被装饰,那么目标的原型被修改并且该字段被转换成一个 属性 和一个隐藏的支持变量来存储 属性 值。
请注意如何不使用箭头函数来定义 getter 和 setter。这就是在设置 property/field 时检索实例的方式。就个人而言,我经常使用箭头函数,以至于在我尝试之前我什至忘记了这样的事情是可能的。
function Field(srcFunc) {
return function (target: any, propertyKey: string, descriptor?: PropertyDescriptor) {
if (descriptor == null) {
const backingKey = `__${propertyKey}`;
Object.defineProperty(target, backingKey, { enumerable: false, writable: true });
Object.defineProperty(target, propertyKey, {
configurable: true,
enumerable: true,
get: function() {
return this[backingKey];
},
set: function(value) {
this[backingKey] = value;
srcFunc.call(this);
}
});
}
else {
const setOriginal = descriptor.set;
descriptor.set = function(value) {
setOriginal.call(this, value);
srcFunc.call(this);
}
}
}
}
export class MyClass {
@Field(MyClass.prototype.myFn)
myProp: string;
private myFn() {
// another code
}
}
我按以下方式在 typescript/angular 中使用装饰器
export function Field({source}){
return (target, property) => {
// Some code here
}
}
那我想这样用
export class MyClass {
constructor(private myService: MyService) {}
@Field({source: () => this.myFn()})
myProp: string;
private myFn() {
// another code
return this.myService.get()
}
}
显然上下文是错误的,"this" 没有引用 MyClass 的实例。 link 使用 MyClass 实例的上下文的最佳方法是什么?
您可以使用迂回方法访问装饰器中的实例,具体取决于您要执行的操作。在下面的示例中,每次设置 属性 时都会调用传递给装饰器的函数。
装饰器将适用于属性和字段。如果一个字段正在被装饰,那么目标的原型被修改并且该字段被转换成一个 属性 和一个隐藏的支持变量来存储 属性 值。
请注意如何不使用箭头函数来定义 getter 和 setter。这就是在设置 property/field 时检索实例的方式。就个人而言,我经常使用箭头函数,以至于在我尝试之前我什至忘记了这样的事情是可能的。
function Field(srcFunc) {
return function (target: any, propertyKey: string, descriptor?: PropertyDescriptor) {
if (descriptor == null) {
const backingKey = `__${propertyKey}`;
Object.defineProperty(target, backingKey, { enumerable: false, writable: true });
Object.defineProperty(target, propertyKey, {
configurable: true,
enumerable: true,
get: function() {
return this[backingKey];
},
set: function(value) {
this[backingKey] = value;
srcFunc.call(this);
}
});
}
else {
const setOriginal = descriptor.set;
descriptor.set = function(value) {
setOriginal.call(this, value);
srcFunc.call(this);
}
}
}
}
export class MyClass {
@Field(MyClass.prototype.myFn)
myProp: string;
private myFn() {
// another code
}
}