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

Posted

技术标签:

【中文标题】使用自定义 TS 装饰器的组件方法中未定义角服务【英文标题】:Angular service is undefined in component method with custom TS decorator 【发布时间】:2018-11-13 18:36:38 【问题描述】:

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

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

下面的示例代码:

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”错误。 关于如何让它发挥作用的任何想法?

【问题讨论】:

我相信如果你有这样的装饰器功能,你应该去掉大括号,所以只有@myCustomDecorator @PierreDuc 好点 - 但注射剂的潜在问题仍然存在...... 我会发布一个比代码更容易阅读的答案:) 【参考方案1】:

如果您立即从装饰器返回描述符,则不应使用大括号 ()this 上下文也丢失了,请尝试使用描述符值中的this。除此之外,当你使用apply 时,你不应该使用扩展运算符。如果你想使用它,你必须使用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;

【讨论】:

【参考方案2】:

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

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

【讨论】:

以上是关于使用自定义 TS 装饰器的组件方法中未定义角服务的主要内容,如果未能解决你的问题,请参考以下文章

带有自定义组件的角包裹角材料标签组件

Sencha Touch - 为啥在我的自定义组件中未定义此功能?

自定义角材料分页器输入

iOS 中未调用自定义委托方法

Angular 5:从自定义装饰器函数内部使用服务

Angular 2自定义弹出组件toast(使用路由)