原文地址:https://www.cnblogs.com/cme-kai/p/8497146.html
參考:https://blog.csdn.net/hlwz5735/article/details/91451784
在OnPush策略下,Angular不會(huì)運(yùn)行變化檢測(cè)(Change Detection ),除非組件的input接收到了新值沫屡。接收到新值的意思是准谚,input的值或者引用發(fā)生了變化。這樣聽(tīng)起來(lái)不好理解眶根,看例子:
子組件接收一個(gè)balls(別想歪:))輸入,然后在模板遍歷這個(gè)balls數(shù)組并展示出來(lái)。初始化2秒后粹舵,往balls數(shù)組push一個(gè)new ball:
注意:因?yàn)槭髽?biāo)鍵盤(pán)事件會(huì)觸發(fā)變化檢測(cè),所以這里使用定時(shí)器骂倘!
現(xiàn)在是不使用OnPush策略的情況眼滤。2秒后,new ball就被添加到視圖中了历涝。
當(dāng)使用OnPush變化檢測(cè)策略的時(shí)候诅需,new ball并不會(huì)被添加到視圖中:
但是,如果在父組件改變input的值荧库,視圖是會(huì)更新的堰塌,因?yàn)檫@樣Angular會(huì)運(yùn)行變化檢測(cè):
這樣就相當(dāng)于改變了balls的引用。
但是电爹,如果不改變balls的引用蔫仙,只給它push一個(gè)值,視圖是不會(huì)更新的:
這時(shí)如果有需要丐箩,我們可以用ChangeDetectorRef.detectChanges()手動(dòng)觸發(fā)變化檢測(cè)摇邦。
開(kāi)啟/關(guān)閉修改檢測(cè)恤煞,并手動(dòng)觸發(fā)
有時(shí)候我們希望關(guān)閉修改檢測(cè),比如這樣的場(chǎng)景:大量數(shù)據(jù)通過(guò)websocket服務(wù)端蜂擁而至施籍,而我們則希望只要每5秒鐘觸發(fā)一次具體UI局部更新就好居扒。為了實(shí)現(xiàn)這種效果,我們先給組件注入修改檢測(cè)器:
如你所見(jiàn)丑慎,我們分離了修改檢測(cè)器喜喂,這會(huì)導(dǎo)致修改檢測(cè)功能的關(guān)閉。之后我們通過(guò)每5秒鐘調(diào)用一次detectChanges()方法來(lái)手動(dòng)觸發(fā)它竿裂。
總結(jié)
Angular默認(rèn)的修改檢測(cè)機(jī)制同Angular 1很類似:它會(huì)在瀏覽器事件之前和之后比較模板表達(dá)式中的值從而確定是否存在修改玉吁。所有的組件都會(huì)執(zhí)行。但是也有一些重要的不同點(diǎn):
第一點(diǎn)是不存在修改檢測(cè)循環(huán)(在Angular 1中稱為消化循環(huán))腻异。這使得僅通過(guò)查看模板和控制器就可以推斷出每個(gè)組件进副。
另一點(diǎn)不同之處,因?yàn)樾薷臋z測(cè)器的構(gòu)建方式不同悔常,組件的修改檢測(cè)機(jī)制比之前快得多影斑。
最后,和Angular 1不同机打, 修改檢測(cè)機(jī)制是可以自定義的矫户。
對(duì)于95%的應(yīng)用場(chǎng)景残邀,可以信誓旦旦地說(shuō)皆辽,Angular的修改檢測(cè)都能良好的工作,并且關(guān)于它我們并不需要了解得太多罐旗。但是弄明白修改檢測(cè)是如何工作的依然有用膳汪,有如下原因:
首先它可以幫助我們弄明白一些在開(kāi)發(fā)時(shí)可能會(huì)遇到的異常信息,如修改檢測(cè)循環(huán)九秀;
有助于我們閱讀異常堆棧追蹤遗嗽,那些突然蹦出來(lái)的zone.afterTurnDone()看起來(lái)終于不那么頭痛了;
在性能短缺(不過(guò)你真的確定不在那些巨型數(shù)據(jù)表格上使用分頁(yè)機(jī)制嗎鼓蜒?)的場(chǎng)景下痹换,理解修改檢測(cè)可以幫助我們進(jìn)行性能優(yōu)化。