简体   繁体   English

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

[英]Angular service is undefined in component method with custom TS decorator

I am trying to add a custom method decorator to an angular component function to add some logging functionality. 我试图将自定义方法装饰器添加到角度组件函数以添加一些日志记录功能。

The component method that I am decorating internally calls an angular service function I injected into the component. 我正在内部装饰的组件方法调用我注入到组件中的角度服务函数。 Unfortunately, when running the code the injected service is picked up as undefined. 不幸的是,在运行代码时,注入的服务被定义为未定义。

The example code below: 下面的示例代码:

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();
  }
}

Causes a "Can't call someServiceFunction of undefined" error. 导致“无法调用未定义的someServiceFunction”错误。 Any ideas on how to get this working? 关于如何使它工作的任何想法?

If you immediately return a descriptor from your decorator, you should not use the braces () . 如果立即从装饰器返回描述符,则不应使用大括号() Also the this context is lost, try using the this which is in the descriptor value. 另外, this上下文也会丢失,请尝试使用描述符值中的this Besides that, when you use apply , you should not use the spread operator. 除此之外,当您使用apply ,您不应使用传播运算符。 If you want to use that, you have to use call : 如果要使用它,则必须使用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;
}

The problem you are facing is caused by the fact that inside the decorator target is the class not the instance of the class. 您面临的问题是由装饰器target内部的类而不是类的实例引起的。 Decorators are applied on class creation, and thus could not have access to the instance when they are called. 装饰器应用于类的创建,因此在调用装饰器时无法访问该实例。 You can acces the current object when the function is actually called: 您可以在实际调用函数时访问当前对象:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM