我有一个装饰器,可以在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);
}
};
};
}
和一个使用HelloComponent
并导入@Log()
中使用的服务的ngOnInit
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();
}
}
但这会导致异常:
错误TypeError:无法读取未定义的属性'sayHello'
如果我从@Log()
中删除了HelloComponent
,那就可以了!
装饰器似乎破坏了以下组件的作用域:
ngOnInit.apply(this, args); // line 13: log.decorator.ts
此呼叫之后,this.helloService
是undefined
的{{1}}中的ngOnInit
,但是如果没有HelloComponent
,@Log()
是{{1 }}实例。
我该如何解决?
Stackblitz上的实时示例: https://stackblitz.com/edit/angular-7hhp5n
答案 0 :(得分:8)
箭头功能强制上下文this
为封闭的词法上下文,它是Log
函数的执行上下文。
要具有组件上下文,应使用简单的函数表达式:
target.prototype.ngOnInit = function( ...args ) {
...
}