角度變化檢測策略:OnPush 和默認策略

已發表: 2021-06-18

變更檢測被稱為檢查當前狀態和新狀態的機制。 這兩種狀態之間的任何差異都表明存在需要更新的更改。 這意味著視圖必須隨著數據的變化而更新。

在應用程序更改期間組件中發生的任何更改都可以通過Angular 2+ 檢測到。 每當模型發生變化時,相關的變化都會被 angular 檢測到,並且視圖會立即更新。 這種變化稱為角度變化檢測。

更改可能是從網絡請求接收到的數據的結果,也可能是通過用戶事件發生的。 隨著應用程序大小的增加,必須通過更改檢測方法執行更多工作。 角度檢測對於在底層視圖和相應模型之間保持同步是必要的。

角度模型的變化可能是由於以下任何原因:

  • DOM 事件(單擊、懸停等)
  • AJAX 請求
  • 計時器 (setTimer(), setInterval())

目錄

先決條件

要掌握本文,您可能必須熟悉角度組件的概念。 此外,值類型和引用類型的概念可能有助於理解本文。

Angular中的變化檢測

角度變化檢測分兩步完成,第一步是通過開發人員更新應用程序模型 它可以通過發出事件或通過更改組件的屬性來進行。 第二步,即角度反映模型的工作。 它檢測是否有任何新數據顯式推送到組件中。 這可以通過組件或使用異步管道訂閱的 Observable 來完成。

因此,這兩個步驟是:

  • 更新應用模型(開發者);
  • 在視圖中反映模型的狀態(Angular)。

角度變化檢測檢測常見瀏覽器事件的變化,如鼠標點擊、HTTP 請求和其他類型的事件。 一旦檢測到變化,就決定是否需要更新視圖。

變更檢測策略

存在兩種角度變化檢測策略,即默認策略和 onPush。

默認策略

  • 模型上的更改由角度監控,以確保捕獲模型中的所有更改。 通過角度檢查新狀態和先前狀態之間的差異。
  • 對於要更新的視圖,角度應該可以訪問新值,然後將其與舊值進行比較。 基於此決定是否更新視圖。
  • 因此,在默認策略中,角度圍繞值是否有任何變化的問題。
  • 沒有關於組件依賴於何處的假設。 這是一種保守的策略,只要有相關的變化就會檢查。 將對任何瀏覽器事件、時間、承諾和 XHR 執行檢查。
  • 當需要考慮包含許多組件的大型應用程序時,該策略可能會出現問題。
  • 默認情況下,它使用ChangeDetectionStrategy.Default策略。

覆蓋瀏覽器的默認機制

  • 幾個低級 API 將在啟動時通過 Angular 進行修補。 這些 API 可能是addEventListener; 用於註冊瀏覽事件瀏覽器函數。
  • addEventListener被 angular 替換,新版本的性能與早期版本一樣。
  • addEventListener新版本向事件處理程序添加了更多功能 通過 Angular 運行性能檢查後更新 UI。

在職的

Zone.js 附帶的庫對瀏覽器 API 進行低級修補。

  • zone被定義為多個JVM執行輪次下的執行內容。 通過這種機制,可以將額外的功能添加到瀏覽器中。 角度內部使用這些區域來檢測任何變化並觸發檢測。
  • 一個區域通常分為三個階段,即開始穩定,區域內有任務運行不穩定,任務完成後穩定。
  • 經過修補以支持更改檢測的瀏覽器機制是:
  1. 瀏覽器事件,例如點擊等。
  2. setInterval() 和 setTimeout()
  3. Ajax HTTP 請求
  • 為了觸發角度變化檢測,Zone.js 用於修補另一個瀏覽器(如 Websockets)的幾個 API。
  • 此方法的一個限制是:如果 Zone.js 不支持瀏覽器 API,則在更改檢測期間將不會觸發。

觸髮變化檢測時角度變化檢測如何工作?

通過變化檢測器檢測觸發的變化。 此更改檢測器是在應用程序啟動期間創建的。 可以考慮TodoItem組件的示例 如果 todo 的狀態被切換,組件將在接收到對象 Todo 時發出事件。 了解有關如何運行 Angular 項目的更多信息。

默認變更檢測機制的工作

變更檢測機制很簡單。 在每個表達式中,將屬性的當前值與表達式中先前狀態的該屬性的值進行比較。

  • 屬性值不同會將isChanged的​​值設置為 true
  1. OnPush 策略
  • 在使用onPush策略時,角度不必對何時必須執行檢查進行任何猜測。
  • 根據輸入參考的變化或組件本身觸發的事件,角度將執行更改檢查。
  • 此外,可以明確要求 angular 執行更改檢查。 這是通過 componentRef.markForCheck() 方法完成的。
  • 此策略中的組件將僅取決於其輸入。 只有在以下情況下才會執行變更檢測策略:
  • 輸入參考發生了變化。
  • 模型的組件或其任何子項中存在相關的更改。
  • 當必須執行顯式更改檢測時。
  • 當使用視圖中的異步管道時。
  • 與默認策略相比,onpush 策略主要圍繞兩個問題展開:
  • 引用類型有什麼變化嗎?
  • 如果引用類型的引用有變化,那麼堆內存的值有變化嗎?
  • 它可以防止對組件和子組件進行不必要的檢查。

為組件實現 onPush 策略

只有當一個新的引用作為@Input()值傳遞時,它才會觸發更改檢測。 這些值可以是基本類型,如數字、布爾值、字符串和 null。 也可以使用數組和對象。 修改後的對像或數組不能用於觸發onPush 組件上的更改檢測,因為不會為它們創建新引用。 因此,將傳遞一個新對​​像或數組引用來觸發檢測器檢測變化。

為了避免更改檢測方法中的錯誤,可以通過使用不可變對象和列表在任何地方使用onPush更改檢測來構建應用程序。 可以通過創建新的對象引用來修改不可變對象,因此:

  • 對於每次更改,都會觸發onPush更改檢測。
  • 始終會創建一個新的對象引用,以防止出現錯誤。

在這種情況下,可以使用 Immutable.js,因為它包含對象 (Map) 和列表 (List) 的不可變數據結構。

  • 在組件註解中添加changeDetection參數將實現 onPush 策略。 ChangeDetectorRef也可以用於完全控制,而不是每次都傳遞新的引用

ChangeDetectorRef.detectChanges()

  • 更改檢測的方法可以通過changeDetectorRef的分離重新附加方法手動附加或分離

ChangeDetectorRef.detach()不可變的.js

當使用 onPush 策略進行變更檢測時,如果強制執行不變性總是一個好主意。 在這種情況下,使用 Immutable.js。

immutable.js 是一個庫,用於在 JavaScript 中結合不可變性以及 List、Stack 和 Map 等不可變數據結構。

要在項目中添加 Immutable.js,必須在終端中使用以下命令。 了解有關角度項目的更多信息。

$ npm install immutable –save

要從 Immutable.js 導入數據結構,必須使用以下命令。 在這種情況下,該命令顯示僅導入 List 和 Map 數據結構。

從“不可變”導入 {Map, List} 也可以使用數組。

此外,如果使用 Immutable.js,也會有一些缺點。

  • 使用 API 有點麻煩。
  • 接口無法實現到數據模型,因為庫 Imutable.js 不支持任何接口。

從世界頂級大學在線學習軟件課程獲得行政 PG 課程、高級證書課程或碩士課程,以加快您的職業生涯。

概括

本文向您介紹了變更檢測的機制和策略。 默認情況下,Angular 將對所有組件執行更改檢測。 此外,當數據發生突變時,可以應用 ChangeDetectorRef 來檢測新引用中的更改。 對角開發的需求不斷增加,這導致了印度的角開發人員工資。

如果你想了解更多關於軟件技術、它的開發以及它背後的機制,你可以查看 upGrad 提供的軟件開發中的執行 PG 程序 - 全棧開發專業化課程。 專業化課程是一個為期 23 週的在線課程,提供 300 多個案例研究,以提高您的知識和可用工具和編程語言,從而提高您的實踐技能。 如果您對課程有任何疑問,請給我們留言。 我們的團隊將與您聯繫。

Angular 中有哪些不同的變更檢測策略?

Angular 提供了幾種變更檢測策略來優化變更檢測的性能。 但是,默認策略名為檢測。 在這個過程中,Angular 會遍歷整個組件樹,從根組件到子組件。 每次樹發生變化時,Angular 都會通過調用它們的 _detectChanges 方法來通知組件。 對於使用 OnPush 變更檢測策略的組件,Angular 不會每次都遍歷整個樹。 相反,它比較數據屬性的當前值和以前的值,並僅在發生更改時調用 _detectChanges 方法。 默認情況下,Angular 使用遍歷整個樹的策略。

Angular 中的指令是什麼?

Angular 中的指令是可重用的組件。 指令允許擴展 HTML 詞彙並使其更具動態性。 這是 Angular 中引入的一個新概念,用於擴展用戶界面。 指令是一種特殊類型的組件,可以用作屬性、元素或類。 如果一個組件被用作元素,那麼它被稱為元素指令,如果它被用作屬性,它被稱為屬性指令,如果它被用作類,它是一個類指令。 Angular 提供了大約 11 個內置指令,例如 ng-repeat、ng-show、ng-controller 等。Angular 還提供了創建自定義指令的工具。

Angularjs 中的過濾器是什麼?

除了瀏覽器提供的過濾器之外,AngularJS 還提供了幾個過濾器。 過濾器嚴格用於在向用戶顯示數據之前對其進行格式化。 始終建議使用過濾器過濾數據,以便用戶每次都能看到相同的數據。 過濾器也可用於使數據驗證更有效。 Angular.js 過濾器允許您獲取一段 HTML 並根據您的意願對其進行操作,例如大寫、小寫等。過濾器允許您獲取一組值並根據這些值創建一個對象列表。