【问题标题】:Typescript decorator and this context打字稿装饰器和这个上下文
【发布时间】:2020-09-14 19:42:44
【问题描述】:

我通过以下方式在 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 的实例。 将此上下文与 MyClass 实例链接的最佳方法是什么?

【问题讨论】:

  • 我不认为你可以在实例级别修改东西,但你应该可以在原型级别进行,也就是说,装饰器可以将那个道具变成原型上的getter @Field({source: MyClass.prototype.myFn)@Field({source: 'myFn')

标签: angular typescript typescript-decorator


【解决方案1】:

您可以使用迂回方法访问装饰器中的实例,具体取决于您要执行的操作。在下面的示例中,每次设置属性时都会调用传递给装饰器的函数。

装饰器适用于属性和字段。如果正在修饰字段,则修改目标的原型并将字段转换为具有隐藏支持变量的属性以存储属性值。

请注意,它如何不使用箭头函数来定义 getter 和 setter。这就是在设置属性/字段时可以检索实例的方式。就我个人而言,我经常使用箭头函数,以至于在我尝试之前,我什至忘记了这样的事情。

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

【讨论】:

  • 谢谢,这会奏效。但是,它不会改变这种情况,在更具体的情况下也不会起作用。我更新了我的问题以描述问题所在。即使我放了@Field({source: MyClass.prototype.myFn}),在myFn方法中“this”仍然没有设置。
  • 我希望我知道具体情况。但是我不知道直接在装饰器工厂函数中获取上下文,所以无论我想出什么都将是一个装备。
猜你喜欢
  • 2019-02-03
  • 2018-06-21
  • 2019-07-29
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 2023-02-15
  • 2015-12-12
  • 1970-01-01
相关资源
最近更新 更多