AngularJS:モデルの変更を自動的に検出


103

モデルの値が変更されるたびに、コードを自動的に実行する(サーバーにデータを保存するなど)ようにしたいとします。ng-changeモデルを変更する可能性のある各コントロールに何かを設定することによってこれを行う唯一の方法はありますか?

つまり、ビューを使用すると、明示的に何かを接続する必要なしにモデルが変更されると、物事が正しく変更されます。サーバーに保存するコードを実行できることに類似していますか?何かのようなもの

myModel.on('change', function() {
  $.post("/my-url", ...);
});

あなたがバックボーンのようなもので見るかもしれないように。

回答:


151

{{}}ng-modelやng-model を持つビューでは、Angularが$watch()舞台裏でesを設定しています。

デフォルトでは$watch、参照によって比較されます。3番目のパラメーターを$watchに設定するとtrue、Angularは代わりにオブジェクトの変更を "浅く"監視します。配列の場合、これは配列項目を比較することを意味し、オブジェクトマップの場合、これはプロパティを監視することを意味します。だからこれはあなたが望むことをするはずです:

$scope.$watch('myModel', function() { ... }, true);

更新:Angular v1.2では、このための新しいメソッド`$ watchCollection()が追加されました。

$scope.$watchCollection('myModel', function() { ... });

「浅い」という単語は、参照が追跡されないため、「深い」ではなく比較を説明するために使用されることに注意してください。たとえば、監視対象のオブジェクトに別のオブジェクトへの参照であるプロパティ値が含まれている場合、その参照は比較されません。他のオブジェクト。


1
ああ、素晴らしい!これが文書化されていないように思われる理由はありますか(つまり、角張ったサイトのチュートリアルで$ watchesを直接設定することについて言及していないと思います)?これについてng-change、入力コントロールに(潜在的に複数の)フックを設定する方が良い考えになる悪い点はありますか?
アレック

12
ええ、メインのチュートリアルが$ watchのどこかで言及されているといいですね。このアプローチの「悪い」点は、モデルが大きい場合に時間がかかる可能性があることです(すべてのダイジェストサイクル-入力フィールドのすべてのキーストローク-このモデルは、ダーティチェックが行われる可能性があり、複数回実行されます)。 。その場合、選択的な$ watch()esまたは選択的なng-changeの方が優れています。
Mark Rajcok 2013年

8

また、フォーム要素をその状態(変更済み/未変更)に従って動的にスタイル設定する必要がある場合、または一部の値が実際に変更されたかどうかをテストする必要がある場合は、自分で開発した次のモジュールを使用できます:https : //github.com/betsol / angular-input-modified

追加のプロパティとメソッドをフォームとその子要素に追加します。これを使用すると、一部の要素に新しいデータが含まれているかどうかをテストしたり、フォーム全体に新しい未保存のデータがあるかどうかをテストしたりできます。

次の監視を設定できます。$scope.$watch('myForm.modified', handler)フォームエレメントに実際に新しいデータが含まれている場合、または初期状態に戻された場合、ハンドラーが呼び出されます。

また、modified個々のフォーム要素のプロパティを使用して、AJAX呼び出しを介してサーバーに送信されるデータの量を実際に減らすことができます。変更されていないデータを送信する必要はありません。

おまけとして、フォームのreset()メソッドの呼び出しによってフォームを初期状態に戻すことができます。

ここでモジュールのデモを見つけることができます:http : //plnkr.co/edit/g2MDXv81OOBuGo6ORvdt?p=preview

乾杯!


これをコントローラで確認する方法はありますか?たとえば、xボタンをクリックした場合、if(myform.modified)の確認ポップアップを表示できますか?
Flash

もちろん、自分のコントローラの機能にFormControllerを渡します:<form name="myForm"><button ng-click="vm.doSomething(myForm)">
Slava Fomin II

おかげで、これはフォームが正しく変更された場合にのみ何かをしますか?
フラッシュ

これはコントローラーFormControllerdoSomething()機能に渡されます。あなたはその関数の中でそれを使ってあなたがやりたいことを何でもすることができます、例えばFormController.modifiedbooleanプロパティをチェックすることによってフォームが実際に変更されているかどうかをチェックします。
Slava Fomin II

ありがとう!素晴らしい機能
Flash
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.