使用自定义TS装饰器的组件方法中未定义角度服务

时间:2018-06-04 12:12:54

标签: angular typescript decorator

我正在尝试向角度组件函数添加自定义方法装饰器以添加一些日志记录功能。

我在内部装饰的组件方法调用我注入组件的角度服务函数。 不幸的是,在运行代码时,注入的服务被选为未定义的。

以下示例代码:

function myCustomDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalValue = descriptor.value;
  descriptor.value = function(...args: any[]) {
    const result = originalValue.apply(target, ...args);
    //Do some other stuff
    return result;
  }
  return descriptor;
}

@Component()
class myComponentClass implements OnInit {
  constructor(private myService: MyService) {}

  ngOnInit() {
    this.functionIWantToDecorate();
  }

  @myCustomDecorator
  private functionIWantToDecorate() {
    this.myService.someServiceFunction();
  }
}

导致“无法调用未定义的someServiceFunction”错误。 关于如何使这个工作的任何想法?

2 个答案:

答案 0 :(得分:3)

如果您立即从装饰器返回描述符,则不应使用大括号()。此外,this上下文丢失,请尝试使用描述符值中的this。除此之外,当您使用apply时,不应使用spread运算符。如果您想使用它,则必须使用call

function myCustomDecorator(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  const originalValue = descriptor.value;
  descriptor.value = function(this: Function, ...args: any[]) {
    const result = originalValue.call(this, ...args);
    // or --> const result = originalValue.apply(this, args);
    //Do some other stuff
    return result;
  }
  return descriptor;
}

答案 1 :(得分:2)

您遇到的问题是由于装饰器target内部的类不是类的实例。装饰器应用于类创建,因此在调用它们时无法访问实例。您可以在实际调用函数时访问当前对象:

descriptor.value = function(...args: any[]) {
  const result = originalValue.apply(this, ...args); // this not target 
  //Do some other stuff
  return result;
}