一部のライブラリをカプセル化するコンポーネントがあります。このライブラリのすべてのイベント リスナーの変更検出の悪夢を回避するために、ライブラリは angular ゾーンの外側にスコープが設定されています。
@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>
これは望ましくありません。なぜなら、私はそのイベントをサブスクライブしなかったためです => 検出するものは何もありません。
その問題の解決策は何ですか?
実際の例に興味がある人は、質問の起源はここにあります。