【发布时间】:2019-03-29 21:13:12
【问题描述】:
我有一个装饰器,在 ngOnInit 上写一个 console.log
log.decorator.ts
export function Log(): ClassDecorator {
// Decorator Factory
return (target: Function) => {
const ngOnInit: Function = target.prototype.ngOnInit;
target.prototype.ngOnInit = ( ...args ) => {
console.log('ngOnInit:', target.name);
if ( ngOnInit ) {
ngOnInit.apply(this, args);
}
};
};
}
和一个使用@Log() 并导入ngOnInit 中使用的服务的HelloComponent
hello.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { Log } from './log.decorator';
import { HelloService } from './hello.service';
@Component({
selector: 'hello',
template: `<p>Hello! thanks for help and open the browser console for see the error!</p>`,
styles: [``]
})
// if you remove @Log(), helloService.sayHello() works!
@Log()
export class HelloComponent implements OnInit {
constructor(private helloService: HelloService){}
ngOnInit(){
this.helloService.sayHello();
}
}
但这会导致异常:
ERROR TypeError: Cannot read property 'sayHello' of undefined
如果我从HelloComponent 中删除@Log(),它会起作用!
装饰器似乎破坏了组件范围:
ngOnInit.apply(this, args); // line 13: log.decorator.ts
在此调用之后,this.helloService 在HelloComponent 的ngOnInit 中是undefined,但没有@Log(),this.helloService 是一个HelloService 实例。
我该如何解决这个问题?
Stackblitz 上的实时示例: https://stackblitz.com/edit/angular-7hhp5n
【问题讨论】:
-
我宁愿说没有
this上下文。 -
尝试删除“.prototype”,让“target.prototype.ngOnInit”变成“target.ngOnInit”。
-
关于第一条评论:有一个这样的上下文,但很可能不是你想要的。为新的 ngOnInit 函数使用普通函数(不是箭头函数),因为您希望 this 上下文成为类的一个,而不是装饰器的一个(
target.prototype.ngOnInit = ( ...args ) => {变为target.prototype.ngOnInit = function( ...args ) {)
标签: arrays angular typescript angular7