Justin's Words

AngularJS $watch()

理解 AngularJS$watch()

$watch(watchExpression<string|Function(scope)>, listener, [objectEquality])

$watch() 可以接受两个函数作为参数,第一个参数数返回监控的 $scope 的变量,第二个函数操作该变量的旧值和新值,第三个参数是可选的,类型为 Booleantrue 则表明第一个参数返回的是一个对象,默认为 false,结构:

1
2
3
4
$scope.$watch(function (scope){
return scope.variable;
}, function (newValue, oldValue) {
});

一个例子:

1
2
3
4
5
$scope.$watch(function(scope) {
return scope.data.myVar
}, function(newValue, oldValue) {
document.getElementById("").innerHTML = "" + newValue + "";
});

另一个例子:

1
2
3
4
5
6
7
8
9
var scope = $rootScope;
scope.name = 'misko';
scope.counter = 0;

scope.$watch('name', function(newValue, oldValue) {
scope.counter = scope.counter + 1;
});

scope.$digest;

$watchGroup(watchExpressions<string|Function(scope)>, listener);

允许传入一个字符串数组或一个函数数组进行监控变化。

1
2
3
4
5
6
$scope.names = ['igor', 'matias', 'misko', 'james'];
$scope.dataCount = 4;

$scope.$watchCollection('names', function(newNames, oldNames) {
$scope.dataCount = newNames.length;
});

$apply

$apply 将数据变化和 digest cycle 连为一起。

$apply 可被看作一个连接机制。当被你设置了 $watch$scope 属性改变时,Angular 都会知道,那是因为 Angular 已经知道去监控那些改变,所以如果这种情况在框架中发生时,digest cycle 都会被执行。

然而有时候你会在 Angular 之外手动改变 $scope 的属性,比如某个 scope 属性通过 jQuery 的 $.ajax() 改变,这样的话 Angular 并不能随之执行 digest cycle,此时就得用到 $apply

参考:

AngularJS $watch() , $digest() and $apply()