Qu'est-ce que `$scope` dans AngularJS ? Tutoriel avec exemple

⚡ Résumé intelligent

Dans AngularJS, `$Scope` est l'objet intégré qui lie un contrôleur à sa vue. Cette page explique la création d'un scope, les fonctions de comportement, la hiérarchie parent-enfant, la différence avec `$rootScope` et comment les cycles de digest actualisent les liaisons.

  • 🔗 Rôle de liaison : La variable `$scope` transporte les variables membres d'un contrôleur vers la vue, permettant ainsi aux modèles d'afficher les données sans modifier directement le DOM.
  • ⚙️ Fonctions comportementales : Associez des fonctions à $scope lorsque la vue doit réagir aux clics, aux modifications d'entrée ou à d'autres événements utilisateur.
  • 🌳 Hiérarchie de portée : Les directives telles que ng-controller et ng-repeat créent des portées enfants qui reflètent l'arbre DOM de l'application.
  • 🌍 Portée de $rootScope : Il existe un objet $rootScope par application, qui se comporte comme un objet global que chaque portée enfant peut lire.
  • 🔍 Cycle de digestion : $watch enregistre les écouteurs, $apply entre dans le contexte d'exécution AngularJS et $digest compare les valeurs jusqu'à ce que le modèle se stabilise.
  • 🚀 Habitude de performance : Veillez à ce que les expressions de surveillance soient peu coûteuses, évitez l'accès au DOM à l'intérieur d'elles et appelez $destroy sur les portées qui ne sont plus nécessaires.

Qu'est-ce que $Scope dans AngularJS ?

Qu’est-ce que $scope dans AngularJS ?

$portée dans AngularJS est un objet intégré qui lie essentiellement le « contrôleur » et la « vue ». On peut définir des variables membres dans la portée du contrôleur auxquelles la vue peut ensuite accéder.

Chaque manette dans un AngularJS L'application reçoit sa propre instance de `$scope` via l'injection de dépendances. Tout ce que vous associez à cet objet devient visible par le modèle géré par le contrôleur ; `$scope` se comporte donc comme le modèle de données partagé entre votre application et le modèle de données. JavaLogique du script et votre balisage HTML.

Prenons l'exemple ci-dessous :

$portée dans AngularJS

angular.module('app',[]).controller('HelloWorldCtrl',
	function($scope)
	{
		$scope.message = "Hello World"
	});

Code Explication:

  1. Le nom du module est « app »
  2. Le nom du contrôleur est « HelloWorldCtrl ».
  3. L'objet Scope est l'objet principal utilisé pour transmettre des informations du contrôleur à la vue.
  4. Variable membre ajoutée à l'objet de portée

⚠️ Avertissement concernant la syntaxe : Le .controller() La méthode prend deux arguments : le nom du contrôleur et la fonction de fabrique. Une virgule est donc nécessaire entre les deux. 'HelloWorldCtrl' et function($scope)Omettre la virgule provoque une erreur. Uncaught SyntaxError avant même le démarrage d'AngularJS.

Un seul contrôleur et une seule vue ne représentent que la moitié du tableau. Les applications réelles imbriquent des contrôleurs, répètent des listes et réutilisent des widgets, ce qui signifie que plusieurs contextes coexistent.

Fonctionnement de la hiérarchie des portées et de l'héritage dans AngularJS

Chaque application AngularJS possède une unique portée racine et peut contenir un nombre quelconque de portées enfants. Les directives créent ces portées enfants et les associent à l'élément DOM qu'elles décorent, de sorte que l'arborescence des portées reflète la structure de la page rendue.

Lorsque AngularJS évalue une expression telle que {{siteName}}Il commence par rechercher cette propriété dans la portée associée à l'élément. Si la propriété est absente, la recherche se poursuit dans la portée parente, et ainsi de suite jusqu'à atteindre la portée racine. JavaLes développeurs de scripts connaissent ce comportement sous le nom d'héritage prototypal, et les portées enfants héritent de leurs parents exactement de cette manière.

L'exemple ci-dessous imbrique un contrôleur à l'intérieur d'un autre afin que vous puissiez observer le mécanisme d'héritage.

<div ng-app="scopeDemo">
    <div ng-controller="ParentCtrl">
        Parent scope value: {{siteName}}
        <div ng-controller="ChildCtrl">
            Child reads parent value: {{siteName}}
            Child own value: {{lesson}}
        </div>
    </div>
</div>

<script type="text/javascript">
    var app = angular.module("scopeDemo", []);

    app.controller("ParentCtrl", function($scope) {
        $scope.siteName = "Guru99";
    });

    app.controller("ChildCtrl", function($scope) {
        $scope.lesson = "AngularJS Scope";
    });
</script>

Code Explication:

  1. ParentCtrl définissant siteName dans son propre périmètre.
  2. ChildCtrl ne définit jamais siteName, pourtant la div interne s'affiche toujours Guru99 car la recherche remonte jusqu'à la portée parente.
  3. lesson Elle ne vit que dans la portée enfant, donc la div parente ne peut pas la lire.

Quelles directives créent une nouvelle portée ?

  • ng-controller : crée une portée enfant pour l'élément sur lequel elle est placée.
  • ng-repeat : crée une portée enfant par itération, c'est pourquoi chaque ligne peut contenir des valeurs différentes pour la même expression.
  • Directives personnalisées : peut demander une portée pour enfant, ou une isoler portée qui n'hérite pas délibérément de son parent.
  • Directives des composants : tout ce qui est enregistré auprès de .component() L'assistant reçoit toujours une portée isolée.

Comme les portées enfants sont lues de bas en haut, les développeurs se demandent souvent où se situe l'objet racine de cette chaîne. Cet objet de niveau supérieur est appelé $rootScope.

$scope vs $rootScope : quelle est la différence ?

AngularJS $rootScope La portée `$rootScope` s'applique à l'ensemble de l'application. Une application ne peut avoir qu'une seule `$rootScope`, utilisée comme une variable globale. Chaque `$scope` est une portée enfant, et `$rootScope` est la portée parente, à la racine de l'arborescence. Le tableau ci-dessous compare ces deux objets.

Aspect $scope $rootScope
Instances par application Plusieurs, une par contrôleur ou directive de création de portée Exactement un
Créé par Directives telles que ng-controller et ng-repeat L'injecteur lors de l'amorçage de l'application
Visibilité Son propre élément et tous ses descendants Chaque portée dans l'application
Utilisation typique Données et comportement pour une vue ou une ligne de liste Valeurs globales de l'application, telles qu'un utilisateur connecté
Risque principal Les valeurs deviennent inaccessibles en dehors de la branche Conflits de noms et couplage caché, comme les variables globales

Utilisez `$rootScope` avec parcimonie. Tout ce qui y est placé est accessible pour toute l'application et lisible partout ; un service partagé est donc généralement plus sûr pour l'état global. La documentation officielle Référence $rootScope liste l'API complète.

Savoir où se trouvent les données représente la moitié du travail. L'autre moitié consiste à paramétrer le système pour qu'il réagisse aux actions de l'utilisateur.

Configuration ou ajout de comportements dans AngularJS

Afin de réagir aux événements ou d'exécuter une sorte de calcul/traitement dans la vue, nous devons fournir un comportement à la portée.

Des comportements sont ajoutés aux objets de portée pour répondre à des événements spécifiques pouvant être déclenchés par la vue. Une fois le comportement défini dans le contrôleur, il est accessible par la vue.

Regardons un exemple de la façon dont nous pouvons y parvenir.

Configuration ou ajout d'un comportement

<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta chrset="UTF 8">
    <title>Guru99</title>     
</head>  
<body ng-app="DemoApp">
<h1> Guru99 Global Event</h1>
<script src="https://code.angularjs.org/1.6.9/angular.js"></script>
<div ng-controller="DemoController">
	{{fullName("Guru","99")}}
</div>
<script type="text/javascript">  
	var app = angular.module("DemoApp", []);
	app.controller("DemoController", function($scope) {
    
    $scope.fullName=function(firstName,lastname){
		return firstName + lastname;
		}
	} );
</script> 

</body>  
</html>

Code Explication:

  1. Nous créons un comportement appelé « fullName ». Ce comportement est une fonction qui accepte 2 paramètres (prénom, nom).
  2. Le comportement renvoie alors la concaténation de ces 2 paramètres.
  3. Dans la vue, nous appelons le comportement et transmettons 2 valeurs de «Guru« » et « 99 » qui sont transmis comme paramètres au comportement.

Si la commande est exécutée avec succès, la sortie suivante s'affichera lorsque vous exécutez votre code dans le navigateur.

Sortie :

Configuration ou ajout d'un comportement

Dans le navigateur, vous verrez une concaténation des deux valeurs de Guru et 99 qui ont été transmis au comportement dans le contrôleur.

Les liaisons comme celle ci-dessus s'actualisent automatiquement, et il est important de comprendre le mécanisme qui permet cela avant qu'une application ne prenne de l'ampleur.

Pourquoi Scope Watchers et le cycle de synthèse sont importants

AngularJS assure la cohérence de la vue avec le contexte grâce à la détection des modifications plutôt qu'aux événements de changement. Ce processus repose sur trois API de contexte :

  • $watch: enregistre un écouteur pour une expression. Interpolations telles que {{fullName}} Inscrivez des observateurs pour vous lors de la liaison du modèle.
  • $apply: Elle entre dans le contexte d'exécution d'AngularJS, évalue votre code puis déclenche un digest. Elle est nécessaire uniquement dans les rappels d'événements personnalisés ou les rappels de bibliothèques tierces, car les directives intégrées l'appellent déjà.
  • $digest : parcourt chaque observateur sur $rootScope et ses enfants, en comparant la valeur actuelle avec la précédente, et répète l'opération jusqu'à ce que le modèle cesse de changer.

Étant donné qu'un condensé peut s'exécuter en plusieurs passes, les expressions de surveillance doivent rester peu coûteuses. Évitez d'accéder au DOM à l'intérieur de ces expressions, car la lecture du DOM est beaucoup plus lente que la lecture d'un condensé. JavaPropriété du script.

La profondeur de surveillance influe également sur le coût. La surveillance par référence est la plus rapide et ne prend en compte que le remplacement complet de la valeur. $watchCollection Cette fonction détecte les éléments ajoutés, supprimés ou réorganisés dans un tableau ou un objet. La surveillance par valeur parcourt une structure imbriquée à chaque mise à jour et est l'option la plus coûteuse ; il est donc conseillé de l'utiliser en dernier recours.

FAQ

Un scope isolé n'hérite pas de manière prototypique de son parent. Les directives de composant construites avec l'assistant `.component()` en reçoivent toujours un, ce qui préserve l'indépendance des widgets réutilisables vis-à-vis du contrôleur englobant et empêche toute lecture accidentelle des propriétés du parent.

La fonction `emit` envoie un événement de portée vers le haut, à travers les portées parentes, jusqu'à `$rootScope`, tandis que `broadcast` le diffuse vers le bas, à chaque portée enfant. Les deux sont reçus avec `$on`. Utilisez `broadcast` avec parcimonie, car il parcourt toutes les portées descendantes.

Appelez `scope.$destroy()` lorsqu'une portée enfant n'est plus nécessaire. Cela empêche la propagation du digest dans la portée et permet au ramasse-miettes de récupérer ses modèles. Désinscrivez également les observateurs manuels en appelant la fonction renvoyée par `$watch`.

Des assistants tels que Copilote GitHub Ils génèrent rapidement des modèles de portée standardisés, mais laissent subsister des erreurs, comme une virgule manquante dans l'enregistrement d'un contrôleur. Vérifiez chaque extrait généré par rapport à la documentation officielle. Documentation sur la portée d'AngularJS.

Les assistants IA associent les propriétés `$scope` aux champs de classe des composants et réécrivent la logique `$watch` sous forme de signaux ou de flux RxJS. Associez-les à l'interface officielle. Angulaire Documentez et exécutez des tests unitaires, car les conversions générées omettent souvent les recherches de portée héritées.

Résumez cet article avec :