$scope
オブジェクトをダーティチェックすることによって
Angulararray
は、オブジェクト内の単純なウォッチャーを維持し$scope
ます。いずれかを調べると、呼び出さ$scope
れたが含まれていることがわかります。array
$$watchers
各ウォッチャーは、object
とりわけ含まれています
- ウォッチャーが監視している表現。これは単なる
attribute
名前か、もっと複雑なものかもしれません。
- 式の最後の既知の値。これは、式の現在の計算値と照合して確認できます。値が異なる場合、ウォッチャーは関数をトリガーし、
$scope
をダーティとしてマークします。
- ウォッチャーが汚れている場合に実行される関数。
ウォッチャーの定義方法
AngularJSでウォッチャーを定義する方法はたくさんあります。
明示的にオンにすることが$watch
できattribute
ます$scope
。
$scope.$watch('person.username', validateUnique);
テンプレートに補間を配置でき{{}}
ます(現在のウォッチャーが作成されます$scope
)。
<p>username: {{person.username}}</p>
ng-model
ウォッチャーを定義するなどのディレクティブを要求できます。
<input ng-model="person.username" />
サイクルは、すべての$digest
ウォッチャーを最後の値と照合します
通常のチャネル(ng-model、ng-repeatなど)を介してAngularJSと対話すると、ディレクティブによってダイジェストサイクルがトリガーされます。
ダイジェストサイクルは、そのすべての子の深さ優先探索$scope
です。それぞれについて$scope
object
、その反復を繰り返し、$$watchers
array
すべての式を評価します。新しい式の値が最後の既知の値と異なる場合、ウォッチャーの関数が呼び出されます。この関数は、DOMの一部を再コンパイルし、の値を再計算し$scope
、トリガーしAJAX
request
、必要なことは何でも行うことができます。
すべてのスコープがトラバースされ、すべてのウォッチ式が評価され、最後の値と照合されます。
ウォッチャーがトリガーされた場合、$scope
は汚れています
ウォッチャーがトリガーされると、アプリは何かが変更されたことを認識し、$scope
がダーティとしてマークされます。
ウォッチャー関数は、親上$scope
または親上の他の属性を変更できます$scope
。1つの$watcher
関数がトリガーされた場合、他$scope
の関数がまだクリーンであることを保証できないため、ダイジェストサイクル全体を再度実行します。
これは、AngularJSには双方向のバインディングがあるため、データを$scope
ツリーに戻すことができるためです。$scope
すでに消化されている高い方の値を変更する場合があります。おそらく、の値を変更します$rootScope
。
$digest
が汚れている場合は、$digest
サイクル全体を再度実行します
$digest
ダイジェストサイクルがクリーンになるか(すべての$watch
式が前のサイクルと同じ値になる)、またはダイジェスト制限に達するまで、サイクルを継続的にループします。デフォルトでは、この制限は10に設定されています。
ダイジェスト制限に達すると、AngularJSはコンソールでエラーを発生させます:
10 $digest() iterations reached. Aborting!
ダイジェストはマシンでは難しいですが、開発者にとっては簡単です
ご覧のとおり、AngularJSアプリで何かが変更されるたびに、AngularJSは$scope
階層内のすべてのウォッチャーをチェックして応答方法を確認します。開発者にとって、これは生産性の大きな恩恵です。配線コードをほとんど記述する必要がないため、AngularJSは値が変更されたかどうかを認識し、アプリの残りの部分を変更と一致させます。
マシンの観点からは、これは非常に非効率的であり、ウォッチャーを作成しすぎるとアプリの速度が低下します。Miskoは、古いブラウザでアプリが遅く感じる前に、約4000人のウォッチャーの数字を引用しています。
この制限は、たとえばng-repeat
大きなものを超えた場合に簡単に到達できます。JSON
array
ワンタイムバインディングなどの機能を使用して、ウォッチャーを作成せずにテンプレートをコンパイルすることで、これを軽減できます。
あまりにも多くのウォッチャーを作成しないようにする方法
ユーザーがアプリを操作するたびに、アプリ内のすべてのウォッチャーが少なくとも1回評価されます。AngularJSアプリを最適化することの大きな部分は、$scope
ツリー内のウォッチャーの数を減らすことです。これを行う簡単な方法の1つは、1回のバインディングを使用することです。
めったに変更されないデータがある場合は、次のように::構文を使用して1回だけバインドできます。
<p>{{::person.username}}</p>
また
<p ng-bind="::person.username"></p>
バインディングは、含まれているテンプレートがレンダリングされ、データがにロードされたときにのみトリガーされ$scope
ます。
ng-repeat
これは、アイテムが多い場合に特に重要です。
<div ng-repeat="person in people track by username">
{{::person.username}}
</div>