angular细节问题整理

directive 中监听 controller 多个对象或数组的变化

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
//init
$scope.chartData = {
xdata: [],
ydata: {
guestData: [],
...
}
}

//change data,注意这里必须重新赋值,push 没用
$scope.change = function(){
$scope.chartData.xdata = [1];
$scope.chartData.ydata = {
guestData: [1,2],
browseData: [1,2],
loseData: [1,2],
avgData: [1,2]
};
}

<chart-line xdata="chartData.xdata" ydata="chartData.ydata"></chart-line>

//directive
scope: {
xdata: '=',
ydata: '='
}

//只要 xdata 或 ydata 任意一个对象变化即可
scope.$watchCollection('[xdata, ydata]', function(newVal,oldVal) {
console.log(newVal);
})
//watchGroup 亦可,注意写法差别
scope.$watchGroup(['xdata', 'ydata'], function(newVal,oldVal) {
console.log(newVal);
})

$apply 和 $digest

什么时候用 $apply$digest

1
2
3
4
{{rootName}}
<div ng-controller="testCtrl">
{{name}}
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
app.controller('testCtrl', ['$scope', '$rootScope', function($scope, $rootScope){
$rootScope.rootName = 'rootName';
$scope.name = 'scopeName';

setTimeout(function(){
console.log('in');
$scope.$apply(function(){
$rootScope.rootName = 'rootName2';
$scope.name = 'scopeName2';
});
// $scope.$apply(); 不推荐
},2000);
}]);
  • 当使用非 angular 包装方法,如 setTimeout 等原生 js 方法去改变 model 值的时候,需手动调用 $apply 或 $digest 去更新 view 显示。
  • $apply 会一直向上检查到 $rootScope 变化。$digest 只会检查自己及子 scope 变化。
  • 使用 $apply 时,总是 $scope.$apply(function(){}) 这样使用,因为这样 angular 会 try… catch…

理解 $apply 和 $digest