どのように$scope.$watch
複数の変数を角度にして、そのうちの1つが変更されたときにコールバックをトリガします。
$scope.name = ...
$scope.age = ...
$scope.$watch('???',function(){
//called when name or age changed
})
どのように$scope.$watch
複数の変数を角度にして、そのうちの1つが変更されたときにコールバックをトリガします。
$scope.name = ...
$scope.age = ...
$scope.$watch('???',function(){
//called when name or age changed
})
UPDATE
角度今オファー(1.3以降)は、2つのスコープ方法$watchGroupと$watchCollection。それらは@blazemongerと@kargoldによって言及されています。これは、タイプと値とは独立して動作するはず
:
$scope.$watch('[age,name]', function() { ... }, true);
あなたは、この場合にはtrueに三番目のパラメータを設定する必要があります。
文字列の連結'age + name'
は、このような場合に失敗します:ユーザーがボタンをクリックする前に見て価値が42foo
(42
+ foo
)だろう
<button ng-init="age=42;name='foo'" ng-click="age=4;name='2foo'">click</button>
とクリック42foo
(4
+ 2foo
)後。したがって、時計機能は呼び出されませんでした。そのような場合は表示されないことを保証できない場合は、配列式を使用することをお勧めします。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" rel="stylesheet" />
<script src="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<script src="http://code.angularjs.org/1.2.0-rc.2/angular.js"></script>
<script src="http://code.angularjs.org/1.2.0-rc.2/angular-mocks.js"></script>
<script>
angular.module('demo', []).controller('MainCtrl', function ($scope) {
$scope.firstWatchFunctionCounter = 0;
$scope.secondWatchFunctionCounter = 0;
$scope.$watch('[age, name]', function() { $scope.firstWatchFunctionCounter++; }, true);
$scope.$watch('age + name', function() { $scope.secondWatchFunctionCounter++; });
});
describe('Demo module', function() {
beforeEach(module('demo'));
describe('MainCtrl', function() {
it('watch function should increment a counter', inject(function ($controller, $rootScope) {
var scope = $rootScope.$new();
scope.age = 42;
scope.name = 'foo';
var ctrl = $controller('MainCtrl', { '$scope': scope });
scope.$digest();
expect(scope.firstWatchFunctionCounter).toBe(1);
expect(scope.secondWatchFunctionCounter).toBe(1);
scope.age = 4;
scope.name = '2foo';
scope.$digest();
expect(scope.firstWatchFunctionCounter).toBe(2);
expect(scope.secondWatchFunctionCounter).toBe(2); // This will fail!
}));
});
});
(function() {
var jasmineEnv = jasmine.getEnv();
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function (spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
</script>
</head>
<body></body>
</html>
http://plnkr.co/edit/2DwCOftQTltWFbEDiDlA?p=preview
PS:
コメントに@reblaceで述べたように、値にアクセスすることはもちろん可能です:
$scope.$watch('[age,name]', function (newValue, oldValue) {
var newAge = newValue[0];
var newName = newValue[1];
var oldAge = oldValue[0];
var oldName = oldValue[1];
}, true);
Plunker not working –
@ Ajax3.14:正確には機能していないのは何ですか?私はその問題を再現できません。あなたはジャスミー出力 "Failing 1 spec"を見ることができますか?テストが失敗するため、期待される出力になります(テストのソースコードのコメントを参照)。 – stofl
この回答は私を助けました、ありがとう!このアプローチの美しさは、監視される配列の要素としてnewValue/oldValueにアクセスできることです(例えば、newValue [0]、newValue [1]、oldValue [0]、oldValue [1]) – reblace
$scope.$watch('age + name', function() {
//called when name or age changed
});
これはJSが文字列としてconcatinatingするために動作します。良い答えと正しい1 btw。 – Heinrich
誰かに同じ質問への答えを見つけること - 私の答えは間違っています、この答えは正しいものです。 – callmekatootie
この場合、角度が変更されたフィールドだけでなく結果の連結になるので、コールバックに渡す 'newValue'と 'oldValue'引数を使用しないようにしてください。 –
角度1.3は、特に$ watchGroupを提供この目的のために:
https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watchGroup
これは、式の配列の標準$ watchと同じ最終結果を提供するようです。コード内で意図が明確になるので、好きです。
複数の値を見るために多くの方法があります:
//angular 1.1.4
$scope.$watchCollection(['foo', 'bar'], function(newValues, oldValues){
// do what you want here
});
またはより新しいバージョン
//angular 1.3
$scope.$watchGroup(['foo', 'bar'], function(newValues, oldValues, scope) {
//do what you want here
});
は、より多くの情報のための公式ドキュメントを読む:https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope
誰も持っていません
var myCallback = function() { console.log("name or age changed"); };
$scope.$watch("name", myCallback);
$scope.$watch("age", myCallback);
これは、少しポーリングを意味するかもしれません。 name + age
(これ用)とname
(別の場所)の両方を見ると、Angularは効果的にname
を2回見て、汚れていないかどうかを確認します。
コールバックをインライン展開するのではなく、名前で使用するほうが読みやすくなります。特に私の例よりも良い名前を付けることができれば。
そして、あなたがする必要がある場合には、さまざまな方法で値を見ることができます:あなたはそれを使用することができますが、私の知る限り、それはあなたが見てみましょうしない場合
$scope.$watch("buyers", myCallback, true);
$scope.$watchCollection("sellers", myCallback);
$watchGroup
がいいですグループメンバをコレクションとして、またはオブジェクトが等価であるようにします。
という古い値と新しい値が両方とも同じコールバック関数呼び出し内の式内にある必要がある場合、おそらく他の提案されている解決策が便利です。
コントローラがロードされて初めてコールバック関数を呼び出しますか?コントローラがロードされて初めて呼び出すのを止めることはできませんか? –
$ watch vsのトピックに関する[Ben Nadelの非常に良いブログ記事](http://www.bennadel.com/blog/2566-Scope-watch-vs-watchCollection-In-AngularJS.htm) $ watchCollectionが役に立つかもしれません。 –