angular-day10-$watch-$apply-$digest

$watch 绑定就加监视,再就是$watch手工监视

$watch with true(deep equality)

1
2
3
$scope.$watch('obj',function(xx){
xxx
},true);

type of watches

every scope will have its own watch list, including root scope


下图中c的watcher listener修改了a的值引起第二轮digest


digest process democode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="angular.js"></script>
</head>
<body ng-app='myapp'>
<section ng-controller='ctrl'>
a: <input type="text" ng-model='a' > {{a}} <br>
b: <input type="text" ng-model='b' > {{b}} <br>
c: <input type="text" ng-model='c' > {{c}} <br>
</section>
</body>
<script type="text/javascript">
var module = angular.module('myapp', []);
module.controller('ctrl', ['$scope','$rootScope', function($scope,$rootScope) {
$scope.a=1;
$scope.b=2;
$scope.c=3;
$scope.$watch("a",function (a,old) {
if(a === old) return;
if(a>50){
$scope.b=250;
}
console.log(a + ' => ' + old);
});
$scope.$watch("b",function (a,old) {
if(a === old) return;
console.log(a + ' => ' + old);
});
$scope.$watch("c",function (a,old) {
if(a === old) return;
console.log(a + ' => ' + old);
});
$rootScope.$watch(function(){
console.log("digest loop: ");
})
}]);
</script>
</html>

console output: second level watch actually look like this in ng1.5.8

  • 原来是因为c在a后面只触发了一次, 视频里是c修改a,所以触发了两次囧
1
2
3
4
5
digest loop:
145 => 14
digest loop: (This one shows in the vedio, but not appear on my test case)
250 => 2
digest loop:

digest and angular context

  • 这就是手写jsonp服务不能触发digest的原因, 因为是在js runtime而不是angular runtime执行的代码
    需要manually invoke $apply or $digest


$apply vs $digest

  • $apply calls $digest
  • $apply just $digest call on $rootScope
  • ng-click will call $apply

demo $apply vs $digest

  • 在控制台选择ng-ctroller-scope修改pai的内容, 如 angular.element($0).scope().$parent.pai[3]=3.13145

  • 调用angular.element($0).scope().$digest(), 只会刷新ng-ctroller-scope的内容,因为ng-repeat创建了另外的4个同级scope

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="angular.js"></script>
</head>
<body ng-app='myapp'>
<section ng-controller='ctrl'>
ng-controller-scope: {{pai}}
</section>
<section>
<p ng-repeat="a in pai track by $index">$rootScope : {{a}}</p>
</section>
</body>
<script type="text/javascript">
var module = angular.module('myapp', []);
module.controller('ctrl', ['$scope','$rootScope', function($scope,$rootScope) {
$rootScope.pai = [1,3];
$rootScope.$watch(function(){
console.log("digest loop: ");
})
}]);
</script>
</html>