有一个组件封装了一些库。为了避免所有这个库的事件监听器的变化检测噩梦,库的范围在角度区域之外:
@Component({ ... })
export class TestComponent {
@Output()
emitter = new EventEmitter<void>();
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
// ...
});
}
}
这一切都很清楚和普遍。现在让我们添加事件以发出动作:
@Component({ ... })
export class TestComponent {
@Output()
emitter = new EventEmitter<void>();
private lib: Lib;
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.lib = new Lib();
});
this.lib.on('click', () => {
this.emitter.emit();
});
}
}
问题是这个发射器不会触发变化检测,因为它是在区域外触发的。那么可能的是重新进入该区域:
@Component({ ... })
export class TestComponent {
@Output()
emitter = new EventEmitter<void>();
private lib: Lib;
constructor(private ngZone: NgZone) {}
ngOnInit() {
this.ngZone.runOutsideAngular(() => {
this.lib = new Lib();
});
this.lib.on('click', () => {
this.ngZone.run(() => this.emitter.emit());
});
}
}
最后,我来回答这个问题。this.ngZone.run
即使我没有在父组件中监听此事件,这也会强制进行更改检测:
<test-component></test-component>
这是不想要的,因为,好吧,我没有订阅那个事件=>没有什么可检测的。
有什么办法可以解决这个问题?
对于那些对现实生活中的例子感兴趣的人来说,问题的根源就在这里。