2 votes

Pourquoi la fonction $scope.watch() d'AngularJS cesse-t-elle de fonctionner lorsque je lui demande de surveiller un tableau ?

J'ai une application AngularJS dans laquelle je crée une directive myp-my-directive qui dessine un graphique sur l'écran en fonction de l'attribut my-attribute . Voici comment je m'y prends. Ça marche :

HTML

<myp-my-directive my-attribute="[1, 2, 3]">
</myp-my-directive>

Directive Angular :

myapp.directive('mypMyDirective',function() {
    return {
      restrict:'E',
      scope: {
        myAttribute: '='
      },
      controller: 'StuffCtrl',
      controllerAs: 'stuffCtrl',
      bindToController: true,
      templateUrl: 'myHtml.html'
    };
  }
);

Contrôleur Angulaire :

myapp.controller('StuffCtrl', function($scope) {
    var self = this;

    $scope.$watch(function() {return self.myAttribute;}, function (objVal)
      {
        if (!(typeof objVal === "object" && objVal.length > 0)) {

          var myObject = Object.assign({}, objVal.data);
          // Draw a fancy chart based using d3.js based on myObject
        }
      }
    );
  }
);

Ce qui précède fonctionne.

Mais je viens de me rendre compte que je dois dessiner le graphique sur la base de deux attributs, et pas seulement d'un seul. $scope.$watch au lieu d'une valeur unique, et en passant un argument final true à elle. Pour l'instant (en tant qu'étape intermédiaire), j'ai adapté mon contrôleur pour qu'il prenne un tableau contenant une seule valeur pour voir si cela fonctionne. Mon contrôleur ressemble maintenant à ceci :

myapp.controller('StuffCtrl', function($scope) {
    var self = this;

    $scope.$watch(function() {return [self.myAttribute];}, function (objVal)
      {
        if (!(typeof objVal[0] === "object" && objVal[0].length > 0)) {

          var myObject = Object.assign({}, objVal[0].data);
          // Draw a fancy chart based using d3.js based on myObject
        }
      }
    );
  }, true
);

Mais cela produit l'erreur suivante :

angular.js:13236 RangeError: Maximum call stack size exceeded
    at equals (angular.js:1048)
    at equals (angular.js:1058)
    at equals (angular.js:1074)
    at equals (angular.js:1058)
    at equals (angular.js:1074)
    at equals (angular.js:1058)
    at equals (angular.js:1074)
    at equals (angular.js:1058)
    at equals (angular.js:1074)
    at equals (angular.js:1058)

Pourquoi ? Les deux versions de mon contrôleur ne devraient-elles pas être équivalentes ? Pourquoi l'une fonctionne-t-elle et l'autre non ? Quelle est la meilleure façon d'envoyer un deuxième attribut au contrôleur à partir de la directive ?

3voto

Devidas Kadam Points 836

Pour un tableau, vous devez utiliser $scope.$watchCollection() . lire aquí

essayez ceci

$scope.$watchCollection(function() {return [self.myAttribute];}, function (newVal, oldVal)
  {
    if (!(typeof newVal[0] === "object" && newVal[0].length > 0)) {

      var myObject = Object.assign({}, newVal[0].data);
      // Draw a fancy chart based using d3.js based on myObject
    }
  }
);

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