322 votes

Comment regarder en profondeur un tableau dans angularjs?

Il y a un tableau d'objets dans ma portée, je veux regarder toutes les valeurs de chaque objet.

C'est mon code:

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

Mais quand je modifie les valeurs, par exemple je change TITLE en TITLE2 , le alert('columns changed') n'a jamais sauté.

Comment regarder en profondeur les objets à l'intérieur d'un tableau?

Il y a une démo en direct: http://jsfiddle.net/SYx9b/

537voto

Piran Points 2126

Vous pouvez définir le 3ème argument de $watch sur true :

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

Voir http://docs.angularjs.org/api/ng.$rootScope.Scope#$watch

51voto

wizardwerdna Points 306

Il y a des conséquences de performance à plonger profondément un objet dans votre montre $. Parfois (par exemple, lorsque les modifications ne sont que des poussées et des pops), vous pouvez vouloir $ regarder une valeur facilement calculée, telle que array.length.

43voto

Trevor Senior Points 4901

Si vous êtes en train de regarder un seul tableau, vous pouvez simplement utiliser ce bout de code:

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

exemple

Mais cela ne fonctionne pas avec plusieurs tableaux:

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

exemple

Pour gérer cette situation, j'ai l'habitude de convertir les multiples tableaux je veux regarder en JSON:

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

exemple

@Jssebastian souligné dans les commentaires, JSON.stringify peut être préférable d' angular.toJson comme il peut gérer les membres qui commencent par '$' et d'éventuelles autres cas.

21voto

Jonathan Rowny Points 5801

Il est intéressant de noter que dans Angular 1.1.x et au-dessus, vous pouvez maintenant utiliser $ watchCollection plutôt que $ watch. Bien que le $ watchCollection semble créer des montres peu profondes, il ne fonctionnera pas avec des tableaux d'objets comme vous le souhaitez. Il peut détecter les ajouts et les suppressions dans le tableau, mais pas les propriétés des objets à l'intérieur des tableaux.

12voto

Jin Points 356

$ watchCollection accomplit ce que vous voulez faire. Ci-dessous un exemple copié à partir du site Web angularjs http://docs.angularjs.org/api/ng/type/$rootScope.Scope Bien que pratique, la performance doit être prise en compte, surtout lorsque vous regardez une grande collection.

    $scope.names = ['igor', 'matias', 'misko', 'james'];
      $scope.dataCount = 4;

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

      expect($scope.dataCount).toEqual(4);
      $scope.$digest();

      //still at 4 ... no changes
      expect($scope.dataCount).toEqual(4);

      $scope.names.pop();
      $scope.$digest();

      //now there's been a change
      expect($scope.dataCount).toEqual(3);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X