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.
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 :
angular.module('app',[]).controller('HelloWorldCtrl', function($scope) { $scope.message = "Hello World" });
Code Explication:
- Le nom du module est « app »
- Le nom du contrôleur est « HelloWorldCtrl ».
- L'objet Scope est l'objet principal utilisé pour transmettre des informations du contrôleur à la vue.
- 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:
ParentCtrldéfinissantsiteNamedans son propre périmètre.ChildCtrlne définit jamaissiteName, pourtant la div interne s'affiche toujours Guru99 car la recherche remonte jusqu'à la portée parente.lessonElle 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.
<!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:
- Nous créons un comportement appelé « fullName ». Ce comportement est une fonction qui accepte 2 paramètres (prénom, nom).
- Le comportement renvoie alors la concaténation de ces 2 paramètres.
- 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 :
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.




