由装饰者执行方法

问题描述 投票:1回答:1

我想在角运行DI之后用装饰器执行一个带有当前分量this的函数。

一个例子:

如果在装饰器上执行,我在this上没有translateService

export const TesteDecorator = (actionName): any => {

  return (target?: any, propertyKey?: string): void => {

    Observable.timer(5000).subscribe(() => {
      target[propertyKey](); // when i execute here not have translateService on (this)
    });

  };
};

但是如果构造函数上的execute有translateService。

@Component({
  ...
})
export class TesteComponent {

  constructor(
    private translateService: TranslateService
  ) {
    Observable.timer(1000).subscribe(() => {
      this.teste(); // when i execute here translateService is on the (this)
    });
  }

  @TesteDecorator('ACTION')
  teste() {
    console.log(this);
  }

}

有人能帮我吗?

javascript angular typescript angular5
1个回答
3
投票

问题是装饰器是在类声明上执行的,而target不是类的实例,但它是原型,所以它不包含任何字段。

解决此问题的一种方法是包装现有函数以调用额外代码,并从构造函数中调用该方法:

export const TesteDecorator = (actionName): any => {

    return (target?: any, propertyKey?: string): void => {
        var prevFn: ()=> void = target['testeDecoratorHelper'];
        target['testeDecoratorHelper'] = function() {
            prevFn.call(this);
            setTimeout(() => {
                console.log(propertyKey);
                this[propertyKey](); // when i execute here not have translateService on (this)
            }, 10);
        }   

    };
};

export class TesteComponent {
    constructor(private translateService: TranslateService) {
        this.testeDecoratorHelper();   
        setTimeout(() => {
            this.teste(); // when i execute here translateService is on the (this)
        }, 10);
    }
    testeDecoratorHelper() {
    }
    @TesteDecorator('ACTION')
    teste() {
        console.log(this);
    }
    @TesteDecorator('ACTION')
    teste2() {
        console.log(this);
    }
}

上面的实现不适用于派生类型,但它应该让你开始。

编辑

由于你使用的是Angular而不是testeDecoratorHelper,你也可以使用ngOnInit,它具有自动调用的优点,因此你不必从构造函数中调用它。 (这个建议的10倍)

© www.soinside.com 2019 - 2024. All rights reserved.