$scope.$watch
と の使い方がわかりません$scope.$apply
。公式ドキュメントは役に立ちません。
具体的に理解できない点:
- それらはDOMに接続されていますか?
- モデルの DOM 変更を更新するにはどうすればよいですか?
- それらの間の接続点は何ですか?
私は試したこのチュートリアル$watch
、しかし、との理解が$apply
当然のこととみなされます。
何をすべき$apply
か$watch
、またそれらをどのように適切に使用すればよいか?
ベストアンサー1
AngularJS を理解するには、その仕組みを知っておく必要があります。
ダイジェストサイクルと$scope
まず第一に、AngularJS はいわゆるダイジェスト サイクルの概念を定義します。このサイクルはループと見なすことができ、その間に AngularJS はすべての によって監視されている$scope
すべての変数に変更があるかどうかを確認します。したがって、$scope.myVar
コントローラーで を定義し、この変数が監視対象としてマークされてmyVar
いる場合、ループの各反復での変更を監視するように AngularJS に暗黙的に指示していることになります。
当然、次のような疑問が湧いてきます。すべてが$scope
監視対象になっているのでしょうか? 幸いなことに、そうではありません。 内のすべてのオブジェクトの変更を監視すると$scope
、ダイジェスト ループの評価に非常に長い時間がかかり、パフォーマンスの問題にすぐに直面することになります。そのため、AngularJS チームは、変数を$scope
監視対象として宣言する 2 つの方法を提供しました (以下を参照)。
$watchは$scopeの変更を監視するのに役立ちます
$scope
変数を監視対象として宣言する方法は 2 つあります。
- テンプレート内で式を使用して
<span>{{myVar}}</span>
$watch
サービス経由で手動で追加する
広告 1) これは最も一般的なシナリオであり、これまでにも見たことがあると思いますが、バックグラウンドでウォッチが作成されたことをご存知なかったでしょう。はい、作成されました! AngularJS ディレクティブ (などng-repeat
) を使用しても、暗黙的なウォッチを作成できます。
広告 2) これは、独自のウォッチを作成する方法です。$watch
サービスは、ウォッチに添付された値が$scope
変更されたときにコードを実行するのに役立ちます。 めったに使用されませんが、役立つ場合があります。 たとえば、「myVar」が変更されるたびにコードを実行する場合は、次のようにします。
function MyController($scope) {
$scope.myVar = 1;
$scope.$watch('myVar', function() {
alert('hey, myVar has changed!');
});
$scope.buttonClicked = function() {
$scope.myVar = 2; // This will trigger $watch expression to kick in
};
}
$applyは変更をダイジェストサイクルに統合することを可能にします
$apply
この関数は統合メカニズムとして考えることができます。オブジェクトに直接アタッチされた監視対象の変数$scope
を変更するたびに、AngularJS は変更が発生したことを認識します。これは、AngularJS がそれらの変更を監視することをすでに認識しているためです。したがって、フレームワークによって管理されるコードで変更が発生した場合、ダイジェスト サイクルが続行されます。
ただし、AngularJS の世界外で何らかの値を変更し、その変更が正常に伝播することを確認したい場合があります。次のことを考えてみてください。jQuery$scope.myVar
のハンドラー内で変更される値があります$.ajax()
。これは将来のある時点で発生します。AngularJS は jQuery を待機するように指示されていないため、これが発生するのを待つことができません。
これに対処するために、$apply
が導入されました。これにより、消化サイクルを明示的に開始できます。ただし、これは一部のデータを AngularJS に移行する場合にのみ使用してください (他のフレームワークとの統合)。このメソッドを通常の AngularJS コードと組み合わせて使用しないでください。その場合、AngularJS はエラーをスローします。
これらすべては DOM とどのように関係しているのでしょうか?
さて、これですべて理解できたので、もう一度チュートリアルに従う必要があります。ダイジェスト サイクルは、$scope
何も変更されない限り、すべての にアタッチされているすべてのウォッチャーを評価することで、UI と JavaScript コードが同期された状態を維持できるようにします。ダイジェスト ループでそれ以上変更が行われない場合は、終了したと見なされます。
$scope
オブジェクトは、コントローラー内で明示的に、または{{expression}}
ビュー内のフォームで直接宣言することによって、オブジェクトにアタッチできます。
さらに詳しい情報: