Angular ChangeDetection變更檢測

最近在做項(xiàng)目的過程中遇到一個(gè)問題:在回調(diào)函數(shù)里,數(shù)據(jù)發(fā)生變化時(shí),視圖并沒有相應(yīng)地更新。于是就在網(wǎng)上搜索解決方案,說是將Component中的changeDetection值修改為ChangeDetectionStrategy.OnPush,再在constructor里導(dǎo)入ChangeDetectorRef,最后在數(shù)據(jù)模型發(fā)生變化的地方添加變更檢測的代碼

@Component({
    ...
    changeDetection: ChangeDetectionStrategy.OnPush
})

export class DemoComponent {
    construtor(private cdf: ChangeDetectorRef) {}

    changeData() {
        ... // 回調(diào)函數(shù)
        this.data = {a: 1}; //變化的數(shù)據(jù)
        this.cdf.markForCheck(); // 進(jìn)行標(biāo)注
        this.cdf.detectChanges(); // 要多加一行這個(gè) 執(zhí)行一次變化檢測
    }
}

這樣一來,修改后的數(shù)據(jù)更新在視圖上,問題得到解決。
但是changeDetection是什么? 為什么加上changeDetection相關(guān)內(nèi)容后,數(shù)據(jù)就會(huì)更新在視圖上?沒加之前,為什么有的數(shù)據(jù)更新了,有的沒有更新呢?等等一系列的問題接踵而至。
問題提出來了,現(xiàn)在要做的就是去解決問題。

What

changeDetection是什么呢?它是Angular的一個(gè)特性。當(dāng)組件中的數(shù)據(jù)發(fā)生變化時(shí),Angular自動(dòng)檢測到數(shù)據(jù)變化更新相應(yīng)的視圖。
一般情況下,將數(shù)據(jù)的狀態(tài)以按鈕、表單、鏈接或者圖片形式呈現(xiàn)在視圖上,也就是DOM。所以,我們將數(shù)據(jù)結(jié)構(gòu)作為輸入并生成DOM顯示給用戶這一過程稱之為渲染。

Why

上文中提到數(shù)據(jù)變化,那數(shù)據(jù)為什么會(huì)變化呢?
一般情況下,在進(jìn)行異步的操作之后,數(shù)據(jù)就會(huì)發(fā)生變化。一般有三種情況:

  • Events: click、submit、onmouseup...
  • XHR請求: 從服務(wù)器獲取數(shù)據(jù)
  • Timers: setTimeout()、setInterval()

這些都是異步的,所以,有異步操作執(zhí)行,數(shù)據(jù)就會(huì)發(fā)生變化,也是在這個(gè)時(shí)候通知Angular更新視圖。

Who

剛才說通知Angular更新視圖,那誰來通知Angular呢?NgZone來通知Angular更新視圖。

How

以上,我們了解到ChangeDeteciton是如何觸發(fā)的,但是怎么運(yùn)行的呢?目前,我們所需要注意到的是:每個(gè)組件都有它自己的變更檢測器。
設(shè)想一個(gè)場景:

在一個(gè)組件中,一個(gè)按鈕被點(diǎn)擊,接下來會(huì)發(fā)生什么呢,當(dāng)有數(shù)據(jù)發(fā)生變化時(shí),Ngzone會(huì)做出處理并且通知Angular,最終Angular會(huì)執(zhí)行變更檢測。

正如我們所知的,每個(gè)組件有它自己的變更檢測器,一個(gè)Angular應(yīng)用包含一個(gè)組件樹,因此推斷出一個(gè)angular應(yīng)用也有一個(gè)變更檢測樹。這個(gè)樹可以視為有向圖,其中,數(shù)據(jù)始終從頂部流向底部。

cd-tree(圖片來源于網(wǎng)絡(luò)).png

數(shù)據(jù)從頂部流向底部的原因時(shí)因?yàn)槊總€(gè)單獨(dú)的組件,從根組件開始,每個(gè)組件也始終從上到下執(zhí)行變更檢測。這樣的話,相比循環(huán)數(shù)據(jù)流,單向數(shù)據(jù)流更容易預(yù)測。我們總是知道數(shù)據(jù)來自何處,因?yàn)樗荒軄碜云浣M件。

相關(guān)文檔


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容