ホームページ  >  記事  >  ウェブフロントエンド  >  AngularJS のダーティ チェック メカニズムと $timeout の素晴らしい使い方

AngularJS のダーティ チェック メカニズムと $timeout の素晴らしい使い方

陈政宽~
陈政宽~オリジナル
2017-06-28 14:42:581507ブラウズ

この記事では、AngularJSダーティチェックの仕組みの詳細な説明と、$timeoutの素晴らしい使い方を中心に紹介します。 「ダーティチェック」はAngularの中核となる仕組みの一つであり、双方向バインディングやMVVMモードを実現するための重要な基盤です。興味がある場合は、

||ブラウザ イベント ループと Angular の MVW について学習してください

「ダーティ チェック」は、Angular の中心的なメカニズムの 1 つであり、双方向を実現するための重要な基盤です。バインディングと MVVM モード。

Angular は、双方向バインディングを一連のウォッチ に変換し、これらのウォッチ式の結果が変更されたかどうかを再帰的にチェックします。変更されている場合は、対応するウォッチャー関数を実行します。モデルの値が変更されなくなると、ウォッチャー関数はトリガーされなくなり、完全なダイジェスト サイクルが終了します。

プログラミングの考え方を変えることなく、同じ言語と同じイベント モデルを使用して NodeJS プログラムを迅速に開発できるため、NodeJS は急速に普及し、JavaScript フルスタックもますます人気が高まっています。

Angular は MV* フレームワークであるということをよく聞きます。これは、Angular がブラウザーのイベント モデルを拡張し、独自のコンテキストを確立するためです。

||Angular の $watch 関数

watch 式は非常に柔軟です。関数、$scope のプロパティ名、または string の形式の式にすることができます。 $scope の属性名または式は、最終的に $parse サービスによって対応する関数に解析され、属性値が取得されます。

すべてのウォッチャー関数は、後で $digest で使用できるように、unshift 関数によってscope.$$watchers 配列の先頭に挿入されます。

最後に、$watch 関数は未登録の関数を返します。これを呼び出すと、登録したばかりのウォッチャーを削除できます。

Angular はデフォルトでは深い比較に angular.equals() 関数を使用しないことに注意してください。これは、=== 比較を使用する方が高速であるためです。そのため、配列またはオブジェクトを比較するときに参照をチェックします。これにより、まったく同じ内容の 2 つの表現が異なるものと判断されてしまいます。詳細な比較が必要な場合は、$watch('someExp', function(){...}, true) のように、3 番目のオプションのパラメーター objectEquality を明示的に true に設定する必要があります。

Angular は、配列またはプロパティのグループを監視するための $watchGroup メソッドと $watchCollection メソッドも提供します。

||Angular の $digest 関数

Angular ではブラウザのイベント ループが拡張されると前述しましたが、何が起こっているのでしょうか?

ビュー上のイベント命令によって転送されたイベントを受け入れると、そのようなイベントに応答するために Angular コンテキストに切り替わり、$digest ループがトリガーされます。

$digest ループは実際には 2 つの while ループ で構成されています。それは、$evalAsync を処理する非同期操作キューと、$watch を処理するウォッチャー キューです。

$digest ループが発生すると、現在の $scope とそのすべての子 $scope に登録されているすべてのウォッチャー関数を走査します。

すべてのウォッチャー関数を走査することは、ダーティ チェックのラウンドと呼ばれます。一連のダーティ チェックを実行した後、いずれかのウォッチャーによって監視されている値が変更された場合、すべてのウォッチャー関数が監視している値が変更されなくなったことを報告するまで、別のラウンドのダーティ チェックが実行されます。

$digestループが終了すると、モデル変更結果がDOMに更新されます。これにより、複数の更新をマージできるようになり、DOM プロパティが頻繁に発生するのを防ぎます。

$digest ループが終了する前に、ダーティ チェックが 10 ラウンドを超えた場合、ダーティ チェックが無限にループするのを防ぐために例外がスローされることに注意してください。

いつこの Angular コンテキストに入り、「ダーティ チェック メカニズム」をトリガーしますか?この質問は非常に重要であり、悩ましいところでもあります。

Angular コンテキストに入るすべてのイベントは $digest ループを実行します。 ngModel によって監視されるフォーム インタラクティブ コントロールの場合、文字が入力されるたびにループがトリガーされて $watcher 関数がチェックされ、ビューが適時に更新されるようになります。 Angular1.3 以降では、構成に ngModelOptions を使用して、デフォルトのトリガー方法を変更できます。

||$apply

$digest は 内部関数 であり、通常のアプリケーション コードで直接呼び出すべきではありません。これをアクティブにトリガーしたい場合は、scope.$apply 関数を呼び出す必要があります。これは、Angular の「ダーティ チェック メカニズム」をトリガーする共通のパブリック インターフェイスです。

Angular は知っている動作トリガー メソッドのみを管理でき、すべての Angular 操作シナリオをカバーできるわけではないことに注意してください。このため、サードパーティの jQuery プラグインをカプセル化するときにビューを自動的に更新できず、$scope.$apply を手動で呼び出す必要があります。

jqueryプラグインを統合すると、ダイジェスト進行中のエラーが発生することがあります。バグを取り除いても解決できない場合は、$timeout を使用して解決することを検討できます。

$timeout の素晴らしい使い方

インターフェイスにバインドされている変数が遅延タスクで変更された場合、window.setTimeout は UI インターフェイスを更新するための「ダーティ チェック」をトリガーしません。 $scope.$apply を追加すれば問題は解決すると思うかもしれません。はい、これで UI インターフェースの更新の問題は解決できますが、別の問題が発生する可能性があります:

エラー: $digest は既に進行中です

何が起こっているのですか?ああ、Angular は内部で「ダーティ チェック」を行っています。賢いプログラマは、この問題を解決するために次のコードを巧みに書きました:


function safeApply(scope, fn){ 
  (scope.
phase||scope.$root.
phase) ? fn() : scope.$apply(fn); 
}


このコードでは、apply 関数を実行する前に、まず Angular が内部で「ダーティ チェック」を行っているかどうかをチェックします。そのため、$apply を使用せずに関数を直接実行します。それ以外の場合、ダーティ チェックが有効になっていない場合は、$apply が関数を実行します。はは、「完璧な」解決策ですね。

作者が上記の完璧という単語の周りに引用符を追加していることに注意してください。 Angular には $timeout サービスが組み込まれており、Angular でネイティブ JavaScript window.setTimeout をラッピングすることで実装されます。

$timeout には多くの素晴らしい用途がありますが、$timeout を使用して apply 関数を実装することが最初の解決策ではなく、Angular の組み込み命令を使用する必要があります。

以上がこの記事の全内容です。皆様の学習に役立つことを願っています。また、皆様も Script Home をサポートしていただければ幸いです。

以上がAngularJS のダーティ チェック メカニズムと $timeout の素晴らしい使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。