如何 $watch 角度的多个变量变化 [英] How to $watch multiple variable change in angular
问题描述
如何$scope.$watch
Angular 中的多个变量,并在其中一个变量发生变化时触发回调.
How to $scope.$watch
multiple variables in Angular, and trigger callback when one of them has changed.
$scope.name = ...
$scope.age = ...
$scope.$watch('???',function(){
//called when name or age changed
})
推荐答案
更新
Angular 现在提供两种作用域方法 $watchGroup(自 1.3 起)和 $watchCollection.@blazemonger 和 @kargold 已经提到了这些.
Angular offers now the two scope methods $watchGroup (since 1.3) and $watchCollection. Those have been mentioned by @blazemonger and @kargold.
这应该独立于类型和值工作:
This should work independent of the types and values:
$scope.$watch('[age,name]', function () { ... }, true);
在这种情况下,您必须将第三个参数设置为 true.
You have to set the third parameter to true in this case.
字符串连接 'age + name'
在这种情况下会失败:
The string concatenation 'age + name'
will fail in a case like this:
<button ng-init="age=42;name='foo'" ng-click="age=4;name='2foo'">click</button>
在用户点击按钮之前,观察值将是 42foo
(42
+ foo
),点击后 42foo
(4
+ 2foo
).所以不会调用 watch 函数.所以如果你不能确保这种情况不会出现,最好使用数组表达式.
Before the user clicks the button the watched value would be 42foo
(42
+ foo
) and after the click 42foo
(4
+ 2foo
). So the watch function would not be called. So better use an array expression if you cannot ensure, that such a case will not appear.
<!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
附注:
正如@reblac 在评论中所说,当然可以访问这些值:
As stated by @reblace in a comment, it is of course possible to access the values:
$scope.$watch('[age,name]', function (newValue, oldValue) {
var newAge = newValue[0];
var newName = newValue[1];
var oldAge = oldValue[0];
var oldName = oldValue[1];
}, true);
这篇关于如何 $watch 角度的多个变量变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!