2017-03-23 5 views
14

私は角度のコンテキストの外にある私のservice.tsにfunction noificationHandler()があるとします。 noificationHandler()は第三者によって呼び出され、noificationHandler()は基本的に配列を消費し、自分のサービスに加入しているコンポーネントに配列を送出します。Angular2 zone.run()とChangeDetectorRef.detectChanges()

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"ので、新しいデータ

で更新されていません角度の範囲外です。角度は です。このイベント("notification.msg")が呼び出されると、アンギエ検出は実行されません。

変更検出を呼び出す2つの方法があります。個別に変更

constructor(private service: myService, private ref: ChangeDetectorRef) { 
    this.service.myObservable.subscribe(list => { 
     this.list = list; 
     this.ref.detectChanges(); // <==== manually invoking change detection 
    }); 
} 

両方のオプションが動作を検出するためのコンポーネントを要求することにより、角度のzone.run()

this.registry.subscribe("a2mevent.notification.msg", this.ngZone.run(() => this.noificationHandler.bind(this))); 

2)の内側にnoificationHandler()をラップすることにより

1)!

1)detectChangesは()のみ、独自のコンポーネントの変更を検出しますか、それはまた、子コンポーネントに変化検出を実行します -

A --> root component 
B 
C 
D // my component is here (4 levels of nesting) 

質問を次のように そして、私のコンポーネント構造がありますか?

2)zone.run()は、ルートからリーフまでのすべてのコンポーネントの変更検出をトリガーしますか?

zone.run()とdetectChanges()の中で私は好奇心が強いですのパフォーマンス

答えて

3

どちらも全く異なるものです。

NgZoneは、複数のスコープにインスタンスを実行できるようにアプリケーションのゾーンを提供するライブラリです。

ChangeDetectionは常に親から葉のようです A> B> C detectChanges()を呼び出すと、現在のコンポーネントとその子コンポーネントも呼び出されます。これは、リーフコンポーネントのOnPush changesdetectionStrategyを使用するための最良の方法です。したがって、入力が更新されるときにのみ、それらは変更されます。

また、ApplicationRefはChangeDetectorに似ています。違いは、ルートコンポーネントから最後の子コンポーネントへの変更を検出することです。

ChaneDetectionとNgZoneは

16

ApplicationRef.ticksetTimeout()と同じ)、不要なChangeDetectionを回避し、アプリケーション全体のzone.run()原因変化検出するために、常に最高の組み合わせです。また、イベントリスナーは、ビュー・バインディングまたは全アプリケーションの@HostBinding()原因変更detectionfを使用して(角内または角度によって追加。

ChangeDetectorRef.detectChangesランが原因入力バインディングの、例えば、特定の成分(およびその子孫(該当する場合)のために検出の変更)

Angularsゾーンの外部で実行いくつかのコードはAngularsコードを呼び出すと状態が変化し、検出角度状態が変化したことを知る方法がないので、明示的に起動する必要が変更した場合。

の状態に変化がある場合コンポーネントのローカル(たとえば、コンポーネントフィールド)、ChangeDetectorRef.detectChangesまたはChangeDetectorRef.markforCheckがより効率的です。

たとえば、外部からの呼び出しが別のルートに移動した場合、これは多くのコンポーネントに影響を与える可能性があります。また、非同期呼び出しを引き起こす可能性があるため、 )。 呼び出された直接的および間接的に呼び出されるコード(ObservableとCallsのコールバックなど)がAngularsゾーン内で実行され、Angularがそれらを認識して自動的に変更検出を呼び出すため、zone.run()が最適です。