たとえば、service.tsにangularのコンテキスト外にあるfunction noificationHandler()
があるとします。 noificationHandler()
はサードパーティによって呼び出され、noificationHandler()
は基本的に配列を消費し、彼のサービスにサブスクライブしているコンポーネントに配列を送信します。
service.ts
_ public mySubject: Subject<any> = new Subject();
public myObservable = this.mySubject.asObservable();
constructor() {
this.registry.subscribe("notification.msg",this.noificationHandler.bind(this));
}
noificationHandler(data) {
this.publishUpdate(data)
}
publishUpdate(data) {
this.mySubject.next(data);
}
_
component.ts
_constructor(private service: myService) {
this.service.myObservable.subscribe(list => {
this.list = list;
});
}
_
^^^この時点では、テンプレートは新しいデータで更新されていません
_"notification.msg"
_はアングルのゾーンの外側にあるため、このevent _("notification.msg")
_が呼び出されたとき、angular sの変更検出は実行されません。
現在、変更検出を呼び出す2つの方法があります。
1)noificationHandler()
をangleのzone.run()の内側にラップすることにより
_ this.registry.subscribe("a2mevent.notification.msg", this.ngZone.run(() => this.noificationHandler.bind(this)));
_
2)変更を検出するようにコンポーネントに個別に依頼する
_constructor(private service: myService, private ref: ChangeDetectorRef) {
this.service.myObservable.subscribe(list => {
this.list = list;
this.ref.detectChanges(); // <==== manually invoking change detection
});
}
_
両方のオプションが機能します!そして、私のコンポーネント構造は次のとおりです
_A --> root component
B
C
D // my component is here (4 levels of nesting)
_
質問-
1)detectChanges()は独自のコンポーネントの変更のみを検出しますか、または子コンポーネントの変更検出も実行しますか?
2)zone.run()は、ルートからリーフまでのすべてのコンポーネントの変更検出をトリガーしますか?
Zone.run()とdetectChanges()の中で、performance?
_ApplicationRef.tick
_(setTimeout()
と同じ)およびzone.run()
は、アプリケーション全体の変更検出を引き起こします。また、Angularまたはby Angular(ビューバインディングまたは@HostBinding()
を使用してアプリケーション全体の変更を検出します。
_ChangeDetectorRef.detectChanges
_は、特定のコンポーネント(および、必要に応じて、たとえば入力バインディングのためにその子孫)の変更検出を実行します
Angularのゾーンの外側で実行されているコードがAngularのコードを呼び出して状態を変更する場合、Angularは状態が変更されたことを知る方法がないため、変更検出を明示的に呼び出す必要があります。
状態への変更がコンポーネント(コンポーネントフィールドなど)に対してローカルである場合、_ChangeDetectorRef.detectChanges
_または_ChangeDetectorRef.markforCheck
_の方が効率的です。
たとえば、外部からの呼び出しが別のルートにナビゲートする場合、これは多くのコンポーネントに影響を与える可能性があり、また、非同期呼び出し(およびコールバックが呼び出される)を引き起こす可能性があるため、ルート全体の変更がいつ完了するかは明確ではありません。この場合、zone.run()
がより良いオプションです。直接および間接的に呼び出されるコード(オブザーバブルやプロミスのコールバックなど)は、Angularのゾーン内で実行され、Angularがそれらを認識します変更検出を自動的に呼び出します。
どちらもまったく異なるものです。
NgZoneは、インスタンスを複数のスコープで実行できるように、アプリのゾーンを提供するライブラリです。
ChangeDetectionは、A> B> Cのように常に親から葉へと移動します。detectChanges()を呼び出すと、現在のコンポーネントとその子コンポーネントも呼び出されます。したがって、これは、リーフコンポーネントにOnPush changesdetectionStrategyを使用するための最良のアプローチであるため、入力が更新されたときにのみChangesを検出します。
また、ApplicationRef
はChangeDetectorに似ています。違いは、ルートコンポーネントから最後の子コンポーネントへの変更を検出することです。
ChaneDetectionとNgZoneは、不必要なChangeDetectionを避けるために常に最適な組み合わせです