角度変化検出戦略:OnPushとデフォルト戦略

公開: 2021-06-18

変化検出は、現在の状態を新しい状態にチェックするメカニズムと呼ばれます。 2つの状態の違いは、更新が必要な変更があることを示しています。 これは、データの変更に応じてビューを更新する必要があることを意味します。

アプリの変更中にコンポーネントで発生する変更は、 Angular2+を介して検出されます。 モデルが変更されるたびに、関連する変更が角度によって検出され、ビューがすぐに更新されます。 この変化は、角度の変化検出と呼ばれます。

変更は、ネットワークリクエストから受信したデータの結果であるか、ユーザーイベントを通じて発生する可能性があります。 アプリのサイズが大きくなるにつれて、変更検出の方法でより多くの作業を実行する必要があります。 基になるビューと対応するモデル間の同期を維持するには、角度検出が必要です。

角度モデルの変更は、次のいずれかが原因である可能性があります。

  • DOMイベント(クリック、ホバーなど)
  • AJAXリクエスト
  • タイマー(setTimer()、setInterval())

目次

前提条件

この記事を入手するには、角度コンポーネントの概念に精通している必要があるかもしれません。 また、値型と参照型の概念は、記事を理解するのに役立つ場合があります。

Angularでの変化検出

角度変化の検出は2つのステップで実行され、最初のステップは開発者によるアプリケーションモデルの更新です。 これは、イベントを発行するか、コンポーネントのプロパティを変更することで先行できます。 2番目のステップ、つまりモデルを反映するAngularの仕事。 新しいデータがコンポーネントに明示的にプッシュされているかどうかを検出します。 これは、非同期パイプを使用してサブスクライブされたコンポーネントまたはObservableのいずれかを介して実行できます。

したがって、2つのステップは次のとおりです。

  • アプリケーションモデルを更新します(開発者)。
  • モデルの状態をビュー(角度)に反映します。

角度の変化検出は、マウスクリック、HTTPリクエスト、その他の種類のイベントなどの一般的なブラウザイベントの変化を検出します。 変更が検出されると、ビューの更新が必要かどうかが決定されます。

変化検出戦略

デフォルトの戦略とonPushの2つの角度変化検出戦略があります。

デフォルトの戦略

  • モデルの変更は角度で監視され、モデルのすべての変更がキャプチャされていることを確認します。 新しい状態と以前の状態の違いは、角度によってチェックされます。
  • ビューを更新するには、Angularが新しい値にアクセスできる必要があります。新しい値は古い値と比較されます。 これに基づいて、ビューを更新するかどうかが決定されます。
  • したがって、デフォルトの戦略では、角度は値に変化があるかどうかの問題を中心に展開します。
  • コンポーネントがどこに依存するかについての仮定はありません。 これは、関連する変更がある場合はいつでもチェックする保守的な戦略です。 チェックは、ブラウザのイベント、時間、プロミス、およびXHRに対して実行されます。
  • 大きなアプリケーションを多くのコンポーネントで検討する場合、この戦略は問題になる可能性があります。
  • デフォルトでは、 ChangeDetectionStrategy.Default戦略を使用します。

ブラウザのデフォルトのメカニズムを上書きする

  • いくつかの低レベルAPIは、起動時にAngularによってパッチが適用されます。 これらのAPIはaddEventListenerである可能性があります。 ブラウジングイベントの登録に使用するブラウザ機能。
  • addEventListenerは、以前のバージョンと同様に機能する新しいバージョンangularに置き換えられます。
  • addEventListenerの新しいバージョンによって、イベントハンドラーにさらに多くの機能が追加されます。 角度によるパフォーマンスチェックを実行すると、UIが更新されます。

働く

Zone.jsに同梱されているライブラリは、ブラウザAPIの低レベルのパッチを適用します。

  • ゾーンは、複数のJVM実行ターンの下での実行コンテンツとして定義されます。 このメカニズムを使用して、ブラウザに追加機能を追加できます。 ゾーンは、変更を検出して検出をトリガーするために、Angularによって内部的に使用されます。
  • 通常、ゾーンには3つのフェーズがあります。つまり、開始時に安定し、ゾーン内でタスクが実行されると不安定になり、タスクが完了すると安定します。
  • 変更の検出をサポートするためにパッチが適用されたブラウザメカニズムは次のとおりです。
  1. クリックなどのブラウザイベント。
  2. setInterval()およびsetTimeout()
  3. AjaxHTTPのリクエスト
  • 角度で変更検出をトリガーするために、Zone.jsを使用してWebsocketなどの別のブラウザーのいくつかのAPIにパッチを適用します。
  • このメソッドの制限は次のとおりです。Zone.jsがブラウザーAPIをサポートしていない場合、変更の検出中にトリガーは発生しません。

変化検出がトリガーされた場合、角度変化検出はどのように機能しますか?

トリガーされた変更は、変更検出器を介して検出されます。 この変更検出器は、アプリケーションの起動時に作成されます。 TodoItemコンポーネントの例を考えることができます。 ToDoのステータスが切り替えられた場合、コンポーネントがオブジェクトTodoを受信するとイベントが発行されます。 角度のあるプロジェクトを実行する方法の詳細をご覧ください。

デフォルトの変更検出メカニズムの動作

変化検出のメカニズムは単純なものです。 各式で、プロパティに現在の値が、式の前の状態にあるそのプロパティの値と比較されます。

  • プロパティの値に違いがあると、 isChangedの値がtrueに設定されます
  1. OnPush戦略
  • onPush戦略を使用する場合、 Angularはチェックをいつ実行する必要があるかを推測する必要はありません。
  • 入力参照の変更、またはコンポーネント自体によってトリガーされたイベントに基づいて、Angularは変更のチェックを実行します。
  • また、Angularは、変更のチェックを実行するように明示的に要求できます。 これは、componentRef.markForCheck()のメソッドを介して行われます。
  • この戦略中のコンポーネントは、その入力のみに依存します。 変更検出戦略は、次の場合にのみ実行されます。
  • 入力リファレンスに変更があります。
  • モデルまたはその子のコンポーネントに関連する変更があります。
  • 明示的な変更検出を実行する必要がある場合。
  • ビュー内の非同期パイプが使用されている場合。
  • デフォルトの戦略と比較して、オンプッシュ戦略は主に次の2つの質問を中心に展開します。
  • 参照タイプに変更はありますか?
  • 参照タイプの参照に変更がある場合、ヒープメモリの値に変更はありますか?
  • これにより、コンポーネントおよび子コンポーネントに対する不要なチェックが防止されます。

コンポーネントのonPush戦略の実装

新しい参照が@Input()値として渡された場合にのみ、変更検出がトリガーされます。 値は、数値、ブール値、文字列、nullなどのプリミティブ型の場合があります。 配列とオブジェクトも使用できます。 変更されたオブジェクトまたは配列は、新しい参照が作成されないためonPushコンポーネントで変更検出をトリガーするために使用することはできません。 したがって、新しいオブジェクトまたは配列参照を渡して、検出器が変更を検出するようにトリガーします。

変更検出方法のバグを回避するために、不変のオブジェクトとリストを使用して、あらゆる場所でonPush変更検出を使用してアプリケーションを構築できます。 不変オブジェクトの変更は、新しいオブジェクト参照を作成することで実行できます。したがって、次のようになります。

  • 変更ごとに、 onPush変更検出がトリガーされます。
  • バグの原因を防ぐために、常に新しいオブジェクト参照が作成されます。

このような場合、オブジェクト(Map)とリスト(List)の不変のデータ構造が含まれているため、Immutable.jsを使用できます。

  • コンポーネントアノテーションにchangeDetectionパラメーターを追加すると、onPush戦略が実装されます。 毎回新しい参照を渡す代わりに、 ChangeDetectorRefを使用して完全に制御することもできます。

ChangeDetectorRef.detectChanges()

  • 変更検出の方法は changeDetectorRefのデタッチおよび再アタッチの方法を使用して手動でアタッチまたはデタッチできます。

ChangeDetectorRef.detach()およびImmutable.js

変更検出にonPush戦略を使用する場合、不変性が適用されているかどうかは常に良い考えです。 このような場合、Immutable.jsが使用されます。

immutable.jsは、JavaScriptに不変性を組み込むために作成されたライブラリであり、List、Stack、Mapなどの不変のデータ構造も含まれています。

プロジェクトにImmutable.jsを追加するには、ターミナルで次のコマンドを使用する必要があります。 角度のあるプロジェクトの詳細をご覧ください。

$ npm install immutable –save

Immutable.jsからデータ構造をインポートするには、次のコマンドを使用する必要があります。 このコマンドは、リストのみをインポートし、この場合はデータ構造をマップすることを示しています。

import {Map、List} from'immutable' 配列も使用できます。

また、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で導入されている新しい概念です。 ディレクティブは特殊なタイプのコンポーネントであり、属性、要素、またはクラスとして使用できます。 コンポーネントが要素として使用される場合、それは要素ディレクティブと呼ばれ、属性として使用される場合、それは属性ディレクティブと呼ばれ、クラスとして使用される場合、それはクラスディレクティブです。 ng-repeat、ng-show、ng-controllerなど、Angularによって提供される約11の組み込みディレクティブがあります。Angularには、カスタムディレクティブを作成する機能もあります。

Angularjsのフィルターは何ですか?

AngularJSは、ブラウザーによって提供されるフィルターに加えて、いくつかのフィルターを提供します。 フィルタは、データをユーザーに表示する前にデータをフォーマットする際に厳密に使用されます。 ユーザーが毎回同じデータを表示できるように、フィルターを使用してデータをフィルター処理することを常にお勧めします。 フィルタを使用して、データ検証をより効率的にすることもできます。 Angular.jsフィルターを使用すると、HTMLの一部を取得して、大文字、小文字など、自由に操作できます。フィルターを使用すると、値の配列を取得し、値に基づいてオブジェクトのリストを作成できます。