如何$scope.$watch在Angular中使用多个变量,并在其中之一发生更改时触发回调。
$scope.$watch
$scope.name = ... $scope.age = ... $scope.$watch('???',function(){ //called when name or age changed })
更新
Angular现在提供了两种范围方法$ watchGroup(从1.3开始)和$watchCollection。这些已被@blazemonger和@kargold提及。
这应该独立于类型和值而工作:
$scope.$watch('[age,name]', function () { ... }, true);
在这种情况下,您必须将第三个参数设置为true。
'age + name'在这种情况下,字符串连接将失败:
'age + name'
<button ng-init="age=42;name='foo'" ng-click="age=4;name='2foo'">click</button>
在用户单击按钮之前,监视的值将是42foo(42+ foo),而在单击42foo(4+ 2foo)之后。因此,不会调用watch函数。因此,如果不能确保最好使用数组表达式,则不会出现这种情况。
42foo
42
foo
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);