在我的作用域中有一个对象数组,我想观察每个对象的所有值。

这是我的代码:

function TodoCtrl($scope) {
  $scope.columns = [
      { field:'title', displayName: 'TITLE'},
      { field: 'content', displayName: 'CONTENT' }
  ];
   $scope.$watch('columns', function(newVal) {
       alert('columns changed');
   });
}

但是当我修改值时,例如我将TITLE更改为TITLE2,警报('列已更改')从未弹出。

如何深度观看数组内的对象?

有一个现场演示:http://jsfiddle.net/SYx9b/


当前回答

在我的例子中,我需要监视一个服务,该服务包含一个地址对象,也由其他几个控制器监视。我陷入了一个循环,直到我添加了“true”参数,这似乎是观察对象时成功的关键。

$scope.$watch(function() {
    return LocationService.getAddress();
}, function(address) {
    //handle address object
}, true);

其他回答

如果你只看一个数组,你可以简单地使用这段代码:

$scope.$watch('columns', function() {
  // some value in the array has changed 
}, true); // watching properties

例子

但这对多个数组无效:

$scope.$watch('columns + ANOTHER_ARRAY', function() {
  // will never be called when things change in columns or ANOTHER_ARRAY
}, true);

例子

为了处理这种情况,我通常会将我想要观察的多个数组转换为JSON:

$scope.$watch(function() { 
  return angular.toJson([$scope.columns, $scope.ANOTHER_ARRAY, ... ]); 
},
function() {
  // some value in some array has changed
}

例子

正如@jssebastian在评论中指出的,JSON。Stringify可能比angular更好。toJson,因为它可以处理以“$”开头的成员,也可以处理其他可能的情况。

你可以设置$watch的第3个参数为true:

$scope.$watch('data', function (newVal, oldVal) { /*...*/ }, true);

见https://docs.angularjs.org/api/ng/type/ rootScope.Scope #美元的手表

从Angular 1.1开始。x你也可以使用$watchCollection来观看浅表(只是“第一层”)的集合。

$scope.$watchCollection('data', function (newVal, oldVal) { /*...*/ });

见https://docs.angularjs.org/api/ng/type/ rootScope.Scope # watchCollection美元

在$watch中深潜一个对象会对性能造成影响。有时(例如,当更改仅为推和弹出时),您可能希望$watch一个容易计算的值,例如array.length。

值得注意的是,在Angular 1.1中。x和以上,你现在可以使用$watchCollection而不是$watch。虽然$watchCollection看起来创建的是浅表,所以它不能像你期望的那样处理对象数组。它可以检测数组的添加和删除,但不能检测数组内对象的属性。

这个解决方案对我来说非常有效,我在一个指令中这样做:

范围。看(attrs美元。testWatch, function() {.....},真正的);

true工作得很好,并响应所有更改(添加、删除或修改字段)。

这是一个工作的活塞玩它。

在AngularJS中深度观察一个数组

我希望这对你有用。 如果你有任何问题,请尽管问,我会尽力帮助你的:)