AngularJS
データバインディングのしくみ
サーチ…
備考
したがって、このデータバインディングのコンセプトは開発者にとっては簡単ですが、Angularはすべてのイベントの変更をリッスンしてダイジェストサイクルを実行するため、ブラウザではかなり重いです。このため、ビューにモデルを追加するときは、スコープができるだけ最適化されていることを確認してください
データバインディングの例
<p ng-bind="message"></p>
この 'メッセージ'は、現在の要素コントローラのスコープにアタッチされている必要があります。
$scope.message = "Hello World";
後でメッセージモデルが更新されたとしても、その更新された値はHTML要素に反映されます。角度をコンパイルすると、テンプレート "Hello World"が現在の世界のinnerHTMLに添付されます。 Angularは、ビューにアタッチされたすべてのディレクティブのWatchingメカニズムを維持します。 Watchers配列を反復処理するDigest Cycleメカニズムがあり、モデルの以前の値に変更があった場合、DOM要素が更新されます。
スコープには、オブジェクトに変更が加えられているかどうかが定期的にチェックされていません。スコープに添付されたオブジェクトのすべてが監視されるわけではありません。スコープはプロトタイプ的に$$ WatchersArrayを維持します。スコープは、$ digestが呼び出されたときにのみ、このWatchersArrayを反復処理します。
AngularはWatchersArrayにウォッチャーを追加します
- {{式}} - テンプレート内(および式がある場所)またはng-modelを定義するとき。
- $ scope。$ watch( 'expression / function') - あなたのJavaScriptでは、ウォーニングのためのスコープオブジェクトを添付することができます。
$ watch関数は3つのパラメータを取ります:
- 最初はオブジェクトを返すウォッチャー関数か、式を追加するだけです。
- 2つ目は、オブジェクトに変更があったときに呼び出されるリスナー関数です。 DOMの変更のようなものはすべてこの関数で実装されます。
- 3番目の引数はブール値をとるオプションのパラメータです。真の角度の深いディープがオブジェクトを監視し、その偽の角度がオブジェクトを参照するだけの場合。 $ watchの粗い実装は次のようになります
Scope.prototype.$watch = function(watchFn, listenerFn) {
var watcher = {
watchFn: watchFn,
listenerFn: listenerFn || function() { },
last: initWatchVal // initWatchVal is typically undefined
};
this.$$watchers.push(watcher); // pushing the Watcher Object to Watchers
};
AngularにはDigest Cycleという面白いことがあります。 $ digest()は$ scope。$ digest()の呼び出しの結果として開始されます。 ng-clickディレクティブを使用してハンドラ関数の$ scopeモデルを変更するとします。この場合、AngularJSは自動的に$ digest()を呼び出すことで$ digestサイクルを起動します.ng-clickの他に、モデルを変更するためのいくつかの組み込みディレクティブ/サービスがあります(ng-model、$ timeoutなど) $ダイジェストサイクルを自動的に起動します。 $ digestの大まかな実装は次のようになります。
Scope.prototype.$digest = function() {
var dirty;
do {
dirty = this.$$digestOnce();
} while (dirty);
}
Scope.prototype.$$digestOnce = function() {
var self = this;
var newValue, oldValue, dirty;
_.forEach(this.$$watchers, function(watcher) {
newValue = watcher.watchFn(self);
oldValue = watcher.last; // It just remembers the last value for dirty checking
if (newValue !== oldValue) { //Dirty checking of References
// For Deep checking the object , code of Value
// based checking of Object should be implemented here
watcher.last = newValue;
watcher.listenerFn(newValue,
(oldValue === initWatchVal ? newValue : oldValue),
self);
dirty = true;
}
});
return dirty;
};
JavaScriptのsetTimeout()関数を使用してスコープモデルを更新すると、Angularは変更する可能性のあることを知ることができません。この場合、$ apply()を手動で呼び出すのは私たちの責任です。これは$ダイジェストサイクルをトリガーします。同様に、DOMイベントリスナーを設定し、ハンドラ関数内のいくつかのモデルを変更する指示がある場合は、$ apply()を呼び出して変更が有効になるようにする必要があります。 $ applyの大きなアイデアは、Angularを認識しないコードを実行できることです。そのコードはスコープ上のものを変更する可能性があります。そのコードを$ applyにラップすると、$ digest()の呼び出しが処理されます。 $ apply()の大まかな実装。
Scope.prototype.$apply = function(expr) {
try {
return this.$eval(expr); //Evaluating code in the context of Scope
} finally {
this.$digest();
}
};