144 votes

Comment compter le nombre total de montres sur une page ?

Existe-t-il un moyen, en JavaScript, de compter le nombre de montres angulaires sur l'ensemble de la page ?

Nous utilisons Batarang mais elle ne répond pas toujours à nos besoins. Notre application est grande et nous souhaitons utiliser des tests automatisés pour vérifier si le nombre de montres augmente trop.

Il serait également utile de compter les montres sur une base par contrôleur.

Modifier Voici ma tentative. Il compte les montres dans tout ce qui a la classe ng-scope.

(function () {
    var elts = document.getElementsByClassName('ng-scope');
    var watches = [];
    var visited_ids = {};
    for (var i=0; i < elts.length; i++) {
       var scope = angular.element(elts[i]).scope();
       if (scope.$id in visited_ids) 
         continue;
       visited_ids[scope.$id] = true;
       watches.push.apply(watches, scope.$$watchers);
    }
    return watches.length;
})();

0 votes

Par contrôleur, c'est facile. Chaque $scope a un tableau $$watchers avec le nombre de surveillants sur ce contrôleur (bien, si vous avez un ng-repeat ou quelque chose qui crée une autre portée, cela ne fonctionne pas si bien). Mais je pense qu'il n'y a aucun moyen de voir tous les observateurs dans l'application entière.

9voto

boyomarinov Points 570

Comme je me débattais récemment avec un nombre élevé de surveillants dans mon application, j'ai découvert une bibliothèque formidable, appelée ng-stats - https://github.com/kentcdodds/ng-stats . Il a une configuration minimale et vous donne le nombre de spectateurs sur la page actuelle + la durée du cycle de digestion. Il pourrait également projeter un petit graphique en temps réel.

8voto

Paul Sweatte Points 8668

Dans AngularJS 1.3.2, une countWatchers a été ajoutée au module ngMock :

/\*\*
 \* @ngdoc method
 \* @name $rootScope.Scope#$countWatchers
 \* @module ngMock
 \* @description
 \* Counts all the watchers of direct and indirect child scopes of the current scope.
 \*
 \* The watchers of the current scope are included in the count and so are all the watchers of
 \* isolate child scopes.
 \*
 \* @returns {number} Total number of watchers.
 \*/

  function countWatchers() 
   {
   var root = angular.element(document).injector().get('$rootScope');
   var count = root.$$watchers ? root.$$watchers.length : 0; // include the current scope
   var pendingChildHeads = \[root.$$childHead\];
   var currentScope;

   while (pendingChildHeads.length) 
    {
    currentScope = pendingChildHeads.shift();

    while (currentScope) 
      {
      count += currentScope.$$watchers ? currentScope.$$watchers.length : 0;
      pendingChildHeads.push(currentScope.$$childHead);
      currentScope = currentScope.$$nextSibling;
      }
    }

   return count;
   }

Références

4voto

Gray Fox Points 134

J'ai pris le code ci-dessous directement à partir du $digest la fonction elle-même. Bien entendu, vous devrez probablement mettre à jour le sélecteur d'éléments de l'application ( document.body ) en bas.

(function ($rootScope) {
    var watchers, length, target, next, count = 0;

    var current = target = $rootScope;

    do {
        if ((watchers = current.$$watchers)) {
            count += watchers.length;
        }

        if (!(next = (current.$$childHead ||
                (current !== target && current.$$nextSibling)))) {
            while (current !== target && !(next = current.$$nextSibling)) {
                current = current.$parent;
            }
        }
    } while ((current = next));

    return count;
})(angular.element(document.body).injector().get('$rootScope'));

1voto

erilem Points 2464

Voici les fonctions que j'utilise :

/**
 * @fileoverview This script provides a window.countWatchers function that
 * the number of Angular watchers in the page.
 *
 * You can do `countWatchers()` in a console to know the current number of
 * watchers.
 *
 * To display the number of watchers every 5 seconds in the console:
 *
 * setInterval(function(){console.log(countWatchers())}, 5000);
 */
(function () {

  var root = angular.element(document.getElementsByTagName('body'));

  var countWatchers_ = function(element, scopes, count) {
    var scope;
    scope = element.data().$scope;
    if (scope && !(scope.$id in scopes)) {
      scopes[scope.$id] = true;
      if (scope.$$watchers) {
        count += scope.$$watchers.length;
      }
    }
    scope = element.data().$isolateScope;
    if (scope && !(scope.$id in scopes)) {
      scopes[scope.$id] = true;
      if (scope.$$watchers) {
        count += scope.$$watchers.length;
      }
    }
    angular.forEach(element.children(), function (child) {
      count = countWatchers_(angular.element(child), scopes, count);
    });
    return count;
  };

  window.countWatchers = function() {
    return countWatchers_(root, {}, 0);
  };

})();

Cette fonction utilise un hachage pour ne pas compter plusieurs fois la même portée.

1voto

zd333 Points 181

Il existe une fonction récursive publiée par le blog de Lars Eidnes à l'adresse suivante http://larseidnes.com/2014/11/05/angularjs-the-bad-parts/ pour recueillir le nombre total de spectateurs. Je compare le résultat en utilisant la fonction postée ici et celle postée sur son blog, qui a généré un nombre légèrement supérieur. Je ne peux pas dire laquelle est la plus précise. Je l'ai juste ajouté ici comme une référence transversale.

function getScopes(root) {
    var scopes = [];
    function traverse(scope) {
        scopes.push(scope);
        if (scope.$$nextSibling)
            traverse(scope.$$nextSibling);
        if (scope.$$childHead)
            traverse(scope.$$childHead);
    }
    traverse(root);
    return scopes;
}
var rootScope = angular.element(document.querySelectorAll("[ng-app]")).scope();
var scopes = getScopes(rootScope);
var watcherLists = scopes.map(function(s) { return s.$$watchers; });
_.uniq(_.flatten(watcherLists)).length;

REMARQUE : vous devrez peut-être remplacer "ng-app" par "data-ng-app" pour votre application Angular.

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