Différence entre $ scope et $ rootScope

90

Quelqu'un peut-il expliquer la différence entre $ scope et $ rootScope?

je pense

$ portée:

Nous pouvons obtenir les propriétés ng-model dans un contrôleur particulier à partir de la page particulière en utilisant ceci.


$ rootScope

Nous pouvons obtenir toutes les propriétés ng-model dans n'importe quel contrôleur à partir de n'importe quelle page en utilisant ceci.


Est-ce correct? Ou autre chose?

Sergio Ivanuzzo
la source
@CodeError! Ce que vous voulez dire, ce lien n'aide pas à ma question, il y a $ scope. $ Root, pas un $ rootScope
$ rootScope est au sommet de la hiérarchie de toutes les étendues de votre application angulaire.
Angad

Réponses:

87

"$ rootScope" est un objet parent de tous les objets angulaires "$ scope" créés dans une page Web.

entrez la description de l'image ici

$ scope est créé avec ng-controllertandis que $ rootscope est créé avec ng-app.

entrez la description de l'image ici

Aayushi Jain
la source
67

La principale différence est la disponibilité de la propriété affectée à l'objet. Une propriété affectée avec $scopene peut pas être utilisée en dehors du contrôleur dans lequel elle est définie, tandis qu'une propriété affectée avec $rootScopepeut être utilisée n'importe où.

Exemple: Si dans l'exemple ci-dessous vous remplacez $rootScopepar $scopela propriété department ne sera pas renseignée à partir du premier contrôleur dans le second

angular.module('example', [])
  .controller('GreetController', ['$scope', '$rootScope',
    function($scope, $rootScope) {
      $scope.name = 'World';
      $rootScope.department = 'Angular';
    }
  ])
  .controller('ListController', ['$scope',
    function($scope) {
      $scope.names = ['Igor', 'Misko', 'Vojta'];
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="example">
  <div class="show-scope-demo">
    <div ng-controller="GreetController">
      Hello {{name}}!
    </div>
    <div ng-controller="ListController">
      <ol>
        <li ng-repeat="name in names">{{name}} from {{department}}</li>
      </ol>
    </div>
  </div>
</body>

Ali Sadiq
la source
18

Selon le guide du développeur d'Angular sur les étendues :

Chaque application Angular a exactement une étendue racine, mais peut avoir plusieurs étendues enfants. L'application peut avoir plusieurs étendues, car certaines directives créent de nouvelles étendues enfants (reportez-vous à la documentation des directives pour voir quelles directives créent de nouvelles étendues). Lorsque de nouvelles étendues sont créées, elles sont ajoutées en tant qu'enfants de leur étendue parent. Cela crée une structure arborescente qui est parallèle au DOM où ils sont attachés.

Les contrôleurs et les directives font référence au champ d'application, mais pas l'un à l'autre. Cette disposition isole le contrôleur de la directive ainsi que du DOM. C'est un point important car cela rend les contrôleurs agnostiques, ce qui améliore considérablement l'histoire des tests des applications.

Gary Stafford
la source
13

$rootScopeest disponible dans le monde entier, quel que soit le contrôleur dans lequel vous vous trouvez, alors qu'il $scopen'est disponible que pour le contrôleur actuel et ses enfants.

À M
la source
3

D'une autre manière, nous pouvons regarder cela; $rootScopeest global tandis que $scopelocal. Quand Controllerest attribué à une page, une $scopevariable peut donc être utilisée ici car elle se lie à ce contrôleur. Mais lorsque nous voulons partager sa valeur avec d'autres contrôleurs ou services, alors $rootScopeest utilisé (** il existe des moyens alternatifs, nous pouvons partager des valeurs entre mais dans ce cas, nous voulons utiliser $rootScope).

Votre deuxième question sur la façon dont vous définissez ces deux mots est correcte.

Enfin un peu hors piste, veuillez utiliser $rootScopeavec précaution. Semblable à la façon dont vous utilisez les variables globales, peut être difficile à déboguer et vous pouvez accidentellement modifier la variable globale quelque part dans un minuteur ou quelque chose qui rend votre lecture incorrecte.

Roger
la source
2

Chaque application a au moins un seul rootScope et son cycle de vie est le même que celui de l'application et chaque contrôleur peut avoir sa propre portée, qui n'est pas partagée avec les autres.

Jetez un œil à cet article:

https://github.com/angular/angular.js/wiki/Understanding-Scopes

User_allowed
la source
2

Je vous recommande de lire la documentation officielle détaillée Angular pour les oscilloscopes. Commencez par la section 'Hiérarchies d'étendues':

https://docs.angularjs.org/guide/scope

Essentiellement, $ rootScope et $ scope identifient tous deux des parties spécifiques du DOM dans lesquelles

  • Des opérations angulaires sont effectuées
  • les variables déclarées dans le cadre de $ rootScope ou $ scope sont disponibles

Tout ce qui appartient à $ rootScope est disponible globalement dans votre application Angular, tandis que tout ce qui appartient à une $ scope est disponible dans la partie du DOM à laquelle cette portée s'applique.

Le $ rootScope est appliqué à l'élément DOM qui est l'élément racine de l'application Angular (d'où le nom $ rootScope). Lorsque vous ajoutez la directive ng-app à un élément du DOM, cela devient l'élément racine du DOM dans lequel $ rootScope est disponible. En d'autres termes, les propriétés, etc. de $ rootScope seront disponibles dans toute votre application Angular.

Une portée Angular $ (et toutes ses variables et opérations) est disponible pour un sous-ensemble particulier du DOM au sein de votre application. Plus précisément, la portée $ de tout contrôleur particulier est disponible pour la partie du DOM à laquelle ce contrôleur particulier a été appliqué (en utilisant la directive ng-controller). Notez cependant que certaines directives, par exemple ng-repeat, lorsqu'elles sont appliquées dans une partie du DOM où le contrôleur a été appliqué, peuvent créer des portées enfants de la portée principale - dans le même contrôleur - un contrôleur ne contient pas nécessairement une seule portée.

Si vous regardez le HTML généré lorsque vous exécutez votre application Angular, vous pouvez facilement voir quels éléments DOM `` contiennent '' une portée, car Angular ajoute la classe ng-scope sur tout élément auquel une portée a été appliquée (y compris l'élément racine de l'application, qui a le $ rootScope).

À propos, le signe '$' au début de $ scope et $ rootScope est simplement un identifiant dans Angular pour les éléments réservés par Angular.

Notez que l'utilisation de $ rootScope pour partager des variables, etc. entre les modules et les contrôleurs n'est généralement pas considérée comme une meilleure pratique. Les développeurs JavaScript parlent d'éviter la `` pollution '' de la portée globale en y partageant des variables, car il peut y avoir des conflits plus tard si une variable du même nom est utilisée ailleurs, sans que le développeur se rende compte qu'elle est déjà déclarée sur le $ rootScope. L'importance de cela augmente avec la taille de l'application et l'équipe qui la développe. Idéalement, $ rootScope ne contiendra que des constantes ou des variables statiques, destinées à être cohérentes à tout moment dans l'application. Une meilleure façon de partager des éléments entre les modules peut être d'utiliser des services et des usines, ce qui est un autre sujet!

Chris Halcrow
la source
2

Les deux sont des objets de script Java et la différence est illustrée par le diagramme ci-dessous.

entrez la description de l'image ici

NTB: La
première application angulaire essaie de trouver la propriété de n'importe quel modèle ou fonction dans $ scope, si elle ne trouve pas la propriété dans $ scope, alors elle recherche dans l'étendue parent dans la hiérarchie supérieure. Si la propriété n'est toujours pas trouvée dans la hiérarchie supérieure, angular tente de résoudre dans $ rootscope.

Waqas Ahmed
la source
1

De nouveaux styles, comme AngularJS Styleguide de John Papa , suggèrent que nous ne devrions pas utiliser du tout $scopepour enregistrer les propriétés de la page actuelle. Au lieu de cela, nous devrions utiliser l' controllerAs with vmapproche où la vue se lie à l'objet contrôleur lui-même. Utilisez ensuite une variable de capture pour cela lorsque vous utilisez la syntaxe controllerAs. Choisissez un nom de variable cohérent tel que vm, qui signifie ViewModel.

$scopeCependant, vous aurez toujours besoin du pour ses capacités de surveillance.

Stan
la source