簡體   English   中英

Angular2 zone.run()vs ChangeDetectorRef.detectChanges()

[英]Angular2 zone.run() vs ChangeDetectorRef.detectChanges()

假設我的service.ts中有一個function noificationHandler() ,它位於angular的上下文之外。 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"在angular的區域之外,因此在調用此事件("notification.msg")時不會運行角度變化檢測。

現在有兩種方法可以調用變化檢測。

1)通過將noificationHandler()包裝在angular的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()中,我很好奇哪個性能更好?

ApplicationRef.tick (與setTimeout() )和zone.run()會導致整個應用程序發生更改檢測。 此外,在Angular或Angular中添加的事件偵聽器(使用視圖綁定或@HostBinding()會導致整個應用程序的更改檢測。

ChangeDetectorRef.detectChanges運行特定組件(及其后代,如果適用,例如由於輸入綁定)的更改檢測

如果在Angular的區域外運行的某些代碼調用Angular的代碼並更改狀態,則需要顯式調用更改檢測,因為Angular無法知道狀態已更改。

如果對狀態的更改是組件的本地(例如組件字段),則ChangeDetectorRef.detectChangesChangeDetectorRef.markforCheck更有效。

如果來自外部的呼叫例如導航到不同的路由,這可能會對許多組件產生影響,並且還不清楚整個路由更改何時完成,因為它可能導致異步調用(以及調用回調)。 在這種情況下, zone.run()是更好的選擇,因為直接和間接調用的代碼(如observable和promises的回調)將在Angular的區域內運行,Angular將識別它們並自動調用更改檢測。

兩者都完全不同。

NgZone是一個為您的應用提供區域的庫,因此您可以將實例運行到多個范圍。

ChangeDetection總是從父到葉像A> B> C當你調用detectChanges()時,它也會調用當前組件及其子組件。 因此,這是對葉組件使用OnPush changesdetectionStrategy的最佳方法,因此它們只會在更新輸入時檢測更改。

此外, ApplicationRef類似於ChangeDetector; 區別在於它將檢測從根組件到最后一個子組件的更改。

ChaneDetection和NgZone是最好的組合,總是避免不必要的ChangeDetection

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM