Angular 開発の実践 (5): 変更監視の詳細な分析
変更モニタリングとは
Angular で開発する場合、モデルからビューへの入力バインディング、ビューからモデルへの出力バインディング、ビューとモデル間の双方向バインディングなど、Angular でのバインディングをよく使用します。これらの境界値がビューとモデル間で同期できる理由は、Angular の変更検出によるものです。
簡単に言えば、変更検出は、ビューとモデルの間でバインドされた値が変更されたかどうかを検出するために Angular によって使用され、モデル内でバインドされた値が変更されたことが検出されると、ビューに同期されます。それ以外の場合、それが検出されたとき ビューにバインドされた値が変更されると、対応するバインディング関数がコールバックされます。
変更監視のソース
変更監視の鍵は、最小の粒度で境界値が変更されたかどうかを検出する方法です。では、どのような状況でこれらの境界値が変化するのでしょうか?私たちが使用するいくつかの一般的なシナリオを見てみましょう:
イベント: click/hover/...
@Component({ selector: 'demo-component', template: ` <h1>{{name}}</h1> <button (click)="changeName()">change name</button> ` }) export class DemoComponent { name: string = 'Tom'; changeName() { this.name = 'Jerry'; } }
補間式を通じてテンプレート内の name 属性をバインドします。 名前変更ボタン
をクリックするとname属性の値が変更され、テンプレートビューの表示内容も変更されます。 change name按钮
时,改变了 name 属性的值,这时模板视图显示内容也发生了改变。
XHR/webSocket
@Component({ selector: 'demo-component', template: ` <h1>{{name}}</h1> ` }) export class DemoComponent implements OnInit { name: string = 'Tom'; constructor(public http: HttpClient) {} ngOnInit() { // 假设有这个./getNewName请求,返回一个新值'Jerry' this.http.get('./getNewName').subscribe((data: string) => { this.name = data; }); } }
我们在这个组件的 ngOnInit 函数里向服务器端发送了一个 Ajax 请求,当这个请求返回结果时,同样会改变当前模板视图上绑定的 name 属性的值。
Times: setTimeout/requestAnimationFrame
@Component({ selector: 'demo-component', template: ` <h1>{{name}}</h1> ` }) export class DemoComponent implements OnInit { name: string = 'Tom'; constructor() {} ngOnInit() { // 假设有这个./getNewName请求,返回一个新值'Jerry' setTimeout(() => { this.name = 'Jerry'; }, 1000); } }
我们在这个组件的ngOnInit函数里通过设定一个定时任务,当定时任务执行时,同样会改变当前视图上绑定的name属性的值。
总结
其实,我们不难发现上述三种情况都有一个共同点,即这些导致绑定值发生改变的事件都是异步发生的。
Angular并不是捕捉对象的变动,它采用的是在适当的时机去检验对象的值是否被改动,这个时机就是这些异步事件的发生。
这个时机是由 NgZone 这个服务去掌控的,它获取到了整个应用的执行上下文,能够对相关的异步事件发生、完成或者异常等进行捕获,然后驱动 Angular 的变化监测机制执行。
变化监测的处理机制
通过上面的介绍,我们大致明白了变化检测是如何被触发的,那么 Angular 中的变化监测是如何执行的呢?
首先我们需要知道的是,对于每一个组件,都有一个对应的变化监测器;即每一个 Component 都对应有一个changeDetector
,我们可以在 Component 中通过依赖注入来获取到changeDetector
。
而我们的多个 Component 是一个树状结构的组织,由于一个 Component 对应一个changeDetector
,那么changeDetector
@Component({ selector: 'demo-child', template: ` <h1>{{title}}</h1> <p>{{paramOne}}</p> <p>{{paramTwo}}</p> ` }) export class DemoChildComponent { title: string = '子组件标题'; @Input() paramOne: any; // 输入属性1 @Input() paramTwo: any; // 输入属性2 }
@Component({ selector: 'demo-parent', template: ` <h1>{{title}}</h1> <demo-child [paramOne]='paramOneVal' [paramTwo]='paramTwoVal'></demo-child> <button (click)="changeVal()">change name</button> ` }) export class DemoParentComponent { title: string = '父组件标题'; paramOneVal: any = '传递给paramOne的数据'; paramTwoVal: any = '传递给paramTwo的数据'; changeVal() { this.paramOneVal = '改变之后的传递给paramOne的数据'; } }
実際、上記の 3 つの状況には 1 つの共通点があることを見つけるのは難しくありません。つまり、バインディング値の変更を引き起こすこれらのイベントはすべて非同期で発生します。
Angular はオブジェクトの変更をキャプチャしません。このタイミングは、オブジェクトの値が変更されたかどうかを確認するために使用されます。このタイミングは、これらの非同期イベントの発生です。- このタイミングは NgZone サービスによって制御され、アプリケーション全体の実行コンテキストを取得し、関連する非同期イベントの発生、完了、例外をキャプチャして、Angular の変更監視メカニズムを実行します。
- 変更監視の処理メカニズム
- 上記の紹介を通じて、変更検出がどのようにトリガーされるかがおおよそ理解できました。それでは、Angular では変更監視がどのように実行されるのでしょうか? まず知っておく必要があるのは、各コンポーネントに対応する変更検出器があるということです。つまり、各コンポーネントは
changeDetector
に対応しており、コンポーネント内の依存関係注入を通じて取得できます。changeDetector
に変更します。
changeDetector
に対応するため、changeDetector
もツリー構造で編成されています。 最後に覚えておく必要があるのは、すべての変更の監視はコンポーネント ツリーのルートから始まるということです。 - 例:子コンポーネント:
- 親コンポーネント:
rrreee
上記のコードでは、DemoParentComponent は、ツリー構造の観点から、タグを通じて DemoChildComponent を埋め込みます。は DemoChildComponent のルート ノードであり、DemoChildComponent は DemoParentComponent のリーフ ノードです。 DemoParentComponent のボタンをクリックすると、changeVal メソッドが呼び戻され、変更監視の実行がトリガーされます。変更監視プロセスは次のとおりです。
@Component({ selector: 'demo-parent', template: ` <h1>{{title}}</h1> ` }) export class DemoParentComponent implements OnInit { title: string = '组件标题'; constructor(public cdRef: ChangeDetectorRef) {} ngOnInit() { this.cdRef.detach(); // 停止组件的变化监测,看需求使用不同的方法 } }
OnPush 与 Default 之间的差别:当检测到与子组件输入绑定的值没有发生改变时,变化检测就不会深入到子组件中去。
变化监测类 - ChangeDetectorRef
上面说到我们可以修改组件元数据属性 changeDetection 来修改组件的变化监测策略(ChangeDetectionStrategy.Default 或 ChangeDetectionStrategy.OnPush),除了这个,我们还可以使用 ChangeDetectorRef 来更加灵活的控制组件的变化监测。
Angular 在整个运行期间都会为每一个组件创建 ChangeDetectorRef 的实例,该实例提供了相关方法来手动管理变化监测。有了这个类,我们自己就可以自定义组件的变化监测策略了,如停止/启用变化监测或者按指定路径变化监测等等。
相关方法如下:
markForCheck():把根组件到该组件之间的这条路径标记起来,通知Angular在下次触发变化监测时必须检查这条路径上的组件。
detach():从变化监测树中分离变化监测器,该组件的变化监测器将不再执行变化监测,除非再次手动执行reattach()方法。
reattach():把分离的变化监测器重新安装上,使得该组件及其子组件都能执行变化监测。
detectChanges():手动触发执行该组件到各个子组件的一次变化监测。
使用方法也很简单,直接在组件中注入即可:
@Component({ selector: 'demo-parent', template: ` <h1>{{title}}</h1> ` }) export class DemoParentComponent implements OnInit { title: string = '组件标题'; constructor(public cdRef: ChangeDetectorRef) {} ngOnInit() { this.cdRef.detach(); // 停止组件的变化监测,看需求使用不同的方法 } }
相关推荐:
以上がAngular 開発の実践 (5): 変更監視の詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









HTTP ステータス コード 460 の役割とアプリケーション シナリオの詳細な分析 HTTP ステータス コードは Web 開発の非常に重要な部分であり、クライアントとサーバー間の通信ステータスを示すために使用されます。その中でも、HTTP ステータス コード 460 は比較的特殊なステータス コードであり、この記事ではその役割と適用シナリオを詳しく分析します。 HTTP ステータス コード 460 の定義 HTTP ステータス コード 460 の具体的な定義は「ClientClosedRequest」です。これは、クライアントがリクエストを閉じたことを意味します。このステータス コードは主に次のことを示すために使用されます。

iBatis と MyBatis: 違いと利点の分析 はじめに: Java 開発では永続性が一般的な要件であり、iBatis と MyBatis は広く使用されている 2 つの永続性フレームワークです。これらには多くの類似点がありますが、いくつかの重要な違いと利点もあります。この記事では、これら 2 つのフレームワークの機能、使用法、サンプル コードを詳細に分析することで、読者がより包括的に理解できるようにします。 1. iBatis の機能: iBatis は、SQL マッピング ファイルを使用する古い永続性フレームワークです。

Oracle エラー 3114 の詳細な説明: 迅速に解決する方法、具体的なコード例が必要です Oracle データベースの開発および管理中に、さまざまなエラーが頻繁に発生しますが、その中でもエラー 3114 は比較的一般的な問題です。エラー 3114 は通常、データベース接続に問題があることを示します。これは、ネットワーク障害、データベース サービスの停止、または不適切な接続文字列設定が原因である可能性があります。この記事では、エラー 3114 の原因とこの問題を迅速に解決する方法を詳しく説明し、特定のコードを添付します

Angular.js は、動的アプリケーションを作成するための無料でアクセスできる JavaScript プラットフォームです。 HTML の構文をテンプレート言語として拡張することで、アプリケーションのさまざまな側面を迅速かつ明確に表現できます。 Angular.js は、コードの作成、更新、テストに役立つさまざまなツールを提供します。さらに、ルーティングやフォーム管理などの多くの機能も提供します。このガイドでは、Ubuntu24 に Angular をインストールする方法について説明します。まず、Node.js をインストールする必要があります。 Node.js は、ChromeV8 エンジンに基づく JavaScript 実行環境で、サーバー側で JavaScript コードを実行できます。ウブにいるために

【PHPにおけるミッドポイントの意味と使い方の分析】 PHPでは、ミッドポイント(.)は2つの文字列やオブジェクトのプロパティやメソッドを接続するためによく使われる演算子です。この記事では、PHP における中間点の意味と使用法を詳しく掘り下げ、具体的なコード例を示して説明します。 1. 文字列中間点演算子の接続 PHP での最も一般的な使用法は、2 つの文字列を接続することです。 2 つの文字列の間に . を置くと、それらをつなぎ合わせて新しい文字列を形成できます。 $string1=&qu

Wormhole は、ブロックチェーンの相互運用性のリーダーであり、所有権、制御、許可のないイノベーションを優先する、回復力があり、将来性のある分散システムの作成に重点を置いています。このビジョンの基盤は、技術的専門知識、倫理原則、コミュニティの連携への取り組みであり、シンプルさ、明確さ、そして幅広いマルチチェーン ソリューションで相互運用性の状況を再定義します。ゼロ知識証明、スケーリング ソリューション、機能豊富なトークン標準の台頭により、ブロックチェーンはより強力になり、相互運用性の重要性がますます高まっています。この革新的なアプリケーション環境では、新しいガバナンス システムと実用的な機能が、ネットワーク全体の資産に前例のない機会をもたらします。プロトコル構築者は現在、この新たなマルチチェーンでどのように運用するかに取り組んでいます。

Angular フレームワークのコンポーネントのデフォルトの表示動作は、ブロックレベルの要素ではありません。この設計の選択により、コンポーネント スタイルのカプセル化が促進され、開発者が各コンポーネントの表示方法を意識的に定義することが促進されます。 CSS プロパティの表示を明示的に設定することで、Angular コンポーネントの表示を完全に制御して、目的のレイアウトと応答性を実現できます。

Win11 の新機能の分析: Microsoft アカウントへのログインをスキップする方法 Windows 11 のリリースにより、多くのユーザーは、Windows 11 がより便利で新しい機能をもたらしたことに気づきました。ただし、ユーザーによっては、自分のシステムが Microsoft アカウントに関連付けられることを好まず、この手順をスキップしたい場合があります。この記事では、ユーザーが Windows 11 で Microsoft アカウントへのログインをスキップし、よりプライベートで自律的なエクスペリエンスを実現するのに役立ついくつかの方法を紹介します。まず、一部のユーザーが Microsoft アカウントにログインすることに抵抗がある理由を理解しましょう。一方で、一部のユーザーは次のことを心配しています。
