$watchと$watchの中間的な位置付けの$watchCollection


$watchCollection

AngularJSのデータバインドを支える$watch で見たように、$watch ではオブジェクトの参照を監視するか、またはオブジェクトの中身まですべて監視(deep watch)するかを切り替えることができる。

その 2 種類の $watch の中間に位置付けられる $watchCollection というのもあり、1 階層分だけを監視(shallow watch)してくれる。

配列の場合

配列の場合に $watch、$watchCollection、および $watch (deep watch) がそれぞれどのように異なるのかを見ていく。

$watch

1
2
$scope.results = [ {...}, {...}, ... ];
$scope.$watch('results', function() {...});

$watch の場合、参照が変更されたときだけリスナーが動作する。

1
results[0].title = '';  // 動かない
1
results.push({...});  // 動かない
1
results = [...];  // 動く

$watchCollection

1
2
$scope.results = [ {...}, {...}, ... ];
$scope.$watchCollection('results', function() {...});

$watchCollection の場合、監視している配列に追加、削除などをした場合にも動作する。

1
results[0].title = '';  // 動かない
1
results.push({...});  // 動く
1
results = [...];  // 動く

$watch(deep watch)

1
2
$scope.results = [ {...}, {...}, ... ];
$scope.$watch('results', function() {...}, true);

$watch (deep watch) の場合、なにかしらあれば動作する。

1
results[0].title = '';  // 動く
1
results.push({...});  // 動く
1
results = [...];  // 動く

普通のオブジェクトの場合

1
2
3
4
5
$scope.user = {
  name: 'unknown',
  images: [...]
};
$scope.$watchCollection('user', function() {...});

普通のオブジェクトを対象とした $watchCollection の動作は、監視しているオブジェクトのプロパティ値の変更や、プロパティの追加・削除でも動作する。

1
user.images.push(...);  // 動かない
1
user.name = 'known';  // 動く
1
user.newProperty = 'new prop!';  // 動く
1
user = {...};  // 動く