Maison > interface Web > js tutoriel > Maîtriser $ watch in angularjs

Maîtriser $ watch in angularjs

Lisa Kudrow
Libérer: 2025-02-18 10:47:09
original
728 Les gens l'ont consulté

Mastering $watch in AngularJS

Points de base

  • La fonction $watch dans AngularJS est un outil puissant pour observer les changements de valeurs ou d'expressions variables. Lorsqu'un changement est détecté, il déclenche une fonction de rappel qui est exécutée chaque fois que la variable surveillée change.
  • $watch Utilisez l'opérateur d'égalité de JavaScript (===) pour la comparaison. Si la nouvelle valeur est différente de l'ancienne valeur, la fonction de rappel est déclenchée. Cependant, il convient de noter que par défaut, $watch ne vérifie que l'égalité de référence, ce qui signifie que la fonction de rappel n'est déclenchée que lorsqu'une nouvelle valeur est affectée à la variable surveillée.
  • AngularJS fournit également $watchGroup et $watchCollection en tant que raccourcis pratiques pour configurer respectivement plusieurs moniteurs ou surveiller les tableaux ou objets avec la même fonction de rappel. Cependant, ces méthodes effectuent uniquement une surveillance peu profonde et ne réagissent qu'aux modifications de référence.
  • L'utilisation de $watch, en particulier sur plusieurs variables, peut affecter les performances car les changements dans toutes les variables surveillées doivent être vérifiées pour chaque cycle de résumé. Les développeurs doivent envisager d'utiliser $watchGroup ou $watchCollection en fonction de la situation, ou limiter le nombre de variables surveillées pour améliorer les performances.

Cet article a été examiné par Mark Brown. Merci à tous les pairs examinateurs de SitePoint pour avoir obtenu le contenu de SitePoint à son meilleur!

AngularJS propose de nombreuses options différentes pour utiliser le mode de publication-abonnement via trois méthodes différentes "Watch". Chaque méthode prend des paramètres facultatifs pour modifier son comportement.

La documentation officielle sur $watch est loin d'être exhaustive: après tout, c'est un problème qui dérange AngularJS v1 dans son ensemble. Même les ressources en ligne qui expliquent comment procéder sont au mieux fragmentées.

Ainsi, en fin de compte, il est difficile pour les développeurs de choisir la bonne approche pour une situation particulière. Cela est particulièrement vrai pour les débutants dans AngularJS! Les résultats peuvent être surprenants ou imprévisibles, ce qui entraîne inévitablement des erreurs.

Dans cet article, je suppose que vous connaissez le concept AngularJS. Si vous pensez que vous devez réviser, vous devrez peut-être lire sur $scope, les liaisons, et $apply et $digest.

Vérifiez votre compréhension

Par exemple, quelle est la meilleure façon de surveiller le premier élément d'un tableau? Supposons que nous déclarons un tableau sur notre portée, $scope.letters = ['A','B','C'];

  • Lorsque nous ajouterons des éléments à un tableau, $scope.$watch('letters', function () {...}); déclenchera-t-il sa fonction de rappel?
  • Lorsque nous changeons son premier élément, va-t-il tirer?
  • Où est
  • $scope.$watch('letters[0]', function () {...});? Cela fonctionnera-t-il de la même manière, ou est-ce mieux?
  • ci-dessus, l'élément de tableau est la valeur d'origine: que se passe-t-il si nous remplacons le premier élément par la même valeur?
  • Supposons maintenant que le tableau contient des objets: que se passe-t-il?
  • Quelle est la différence entre
  • $watch, $watchCollection et $watchGroup?

Si vous êtes confus par toutes ces questions, veuillez continuer à lire. Mon objectif est de vous guider à travers le processus en expliquant cela aussi clairement que possible avec quelques exemples.

$scope.$watch

Commençons par $scope.$watch. Voici le cœur de toutes les fonctionnalités de montre: toutes les autres méthodes que nous verrons n'est qu'un raccourci pratique vers $watch.

en utilisant $watch

L'avantage de l'Angular est que vous pouvez explicitement utiliser le même mécanisme pour effectuer des opérations complexes déclenchées par des changements de données dans le contrôleur. Par exemple, vous pouvez configurer un moniteur pour certaines données qui peuvent être modifiées en réponse à:

  1. Timeout
  2. ui
  3. calculs asynchrones complexes effectués par le travailleur Web
  4. Ajax Call

Vous pouvez configurer un seul auditeur pour gérer les modifications de données, quelle que soit la cause.

Cependant, pour ce faire, vous devez vous appeler $scope.$watch.

Fonctionnement pratique

Regardons le code de $rootscope.watch().

C'est sa signature: function(watchExp, listener, objectEquality, prettyPrintExpression).

En détail, ses quatre paramètres:

  1. watchExp Expression surveillée. Il peut s'agir d'une fonction ou d'une chaîne, et il est évalué dans chaque cycle de digestion.

    Un aspect clé à noter ici est que si l'expression est évaluée en fonction, la fonction doit être idempotente. En d'autres termes, pour le même ensemble d'entrée, il doit toujours renvoyer la même sortie. Si ce n'est pas le cas, Angular supposera que les données surveillées ont été modifiées. Cela signifie à son tour qu'il continuera de détecter les différences et d'appeler l'auditeur à chaque itération du cycle de digestion.

  2. listener Une fonction de rappel qui est tirée lors de la configuration du moniteur, puis chaque fois qu'un changement dans la valeur watchExp est détecté pendant le cycle de résumé. L'appel initial au réglage est destiné à stocker la valeur initiale de l'expression.

  3. objectEquality Le moniteur effectuera une comparaison de profondeur si et seulement si cette valeur est vraie. Sinon, il effectue des comparaisons peu profondes, c'est-à-dire uniquement des références de comparaison.

    Prenons le tableau comme exemple: $scope.fruit = ["banana", "apple"];

    signifie que seul la réaffectation du champ objectEquality == false fera appeler l'auditeur. fruit

    Nous devons également vérifier la profondeur du «profond»: nous en discuterons plus tard.

  4. prettyPrintExpression S'il est passé, il remplacera l'expression de surveillance. Ce paramètre n'est pas destiné à être utilisé dans les appels normaux à $watch();

    Méfiez-vous: comme vous pouvez le voir, les résultats inattendus sont sujets à des résultats inattendus lorsque le quatrième paramètre est passé accidentellement.

Maintenant, nous allons répondre à certaines des questions de l'introduction. Veuillez consulter les exemples de cette section:

Exemple de codepen

N'hésitez pas à vous familiariser avec eux; vous pouvez comparer directement les différences de comportement, ou le faire dans l'ordre dans l'article.

Surveillance du tableau

Vous devez donc surveiller le tableau sur la portée pour apporter des modifications, mais que signifie "changer"?

Supposons que votre contrôleur ressemble à ceci:

app.controller('watchDemoCtrl', ['$scope', function($scope){
    $scope.letters = ['A','B','C'];
}]);
Copier après la connexion
Copier après la connexion
Copier après la connexion

Une option consiste à utiliser un appel comme ceci:

$scope.$watch('letters', function (newValue, oldValue, scope) {
    // 对 $scope.letters 执行任何操作
});
Copier après la connexion
Copier après la connexion
Copier après la connexion

Dans le rappel ci-dessus, newValue et oldValue ont des significations auto-explicites et sont mis à jour chaque fois que le cycle $digest l'appelle. La signification de scope est également intuitive, car elle contient des références à la portée actuelle.

Mais la clé est: quand cet auditeur sera-t-il appelé? En fait, vous pouvez ajouter, supprimer, remplacer les éléments dans un tableau sans rien se produire. En effet, par défaut, letters suppose que vous voulez uniquement $watch de référence l'égalité , de sorte que la fonction de rappel est déclenchée uniquement lorsque vous attribuez une nouvelle valeur à . $scope.letters

Si vous devez prendre des mesures sur les modifications de n'importe quel élément du tableau, vous devez passer

comme troisième paramètre à true (c'est-à-dire comme valeur du paramètre watch facultatif décrit ci-dessus). objectEquality

$scope.$watch('letters', function (newValue, oldValue, scope) {
    // 对 $scope.letters 执行任何操作
}, true);
Copier après la connexion
Copier après la connexion
Objet de surveillance

Pour les objets, la situation ne change pas: si

est fausse, vous surveillez simplement toute réaffectation à cette variable de portée, et si elle est vraie, la fonction de rappel sera déclenchée chaque fois que l'élément de l'objet est modifié. objectEquality

Le premier élément du tableau de surveillance

Il convient de noter qu'en surveillant le tableau à l'aide de

, chaque fois que la fonction de rappel est déclenchée, objectEquality === true et newValue sera les valeurs anciennes et nouvelles de l'ensemble du tableau. Vous devez donc les comparer les uns avec les autres pour comprendre ce qui change réellement. oldValue

Supposons que vous ne soyez intéressé que par les modifications du premier élément (ou du quatrième élément - le même principe) dans le tableau. Étant donné qu'angular est excellent, il vous permet de le faire: vous pouvez l'exprimer d'une manière naturelle dans l'expression transmise à

comme premier argument: $watch

$scope.$watch('letters[4]', function (newValue, oldValue, scope) {
    //...
}, true);
Copier après la connexion
Copier après la connexion
Que se passe-t-il si le tableau n'a que 2 éléments? Pas de problème, votre fonction de rappel ne sera pas licenciée à moins que vous ajoutiez un quatrième élément. Ok ok, techniquement, il tire lorsque vous configurez le moniteur, puis uniquement lorsque vous ajoutez le quatrième élément.

Si vous enregistrez oldValue, vous verrez que dans les deux cas, il ne sera pas défini. Comparez cela à ce qui se passe lors de la surveillance des éléments existants: lors de la configuration, vous avez toujours oldValue == undefined. Donc $watch ne peut pas être traité!

une question plus intéressante maintenant: devons-nous passer objectEquality === true ici?

Réponse courte: Désolé, il n'y a pas de réponse courte.

cela dépend vraiment de:

  • Dans cet exemple, comme nous travaillons sur la valeur d'origine, nous n'avons pas besoin de comparaisons de profondeur, nous pouvons donc omettre objectEquality.
  • mais supposons que nous ayons une matrice, par exemple $scope.board = [[1, 2, 3], [4, 5, 6]]; et nous voulons surveiller la première ligne. Ensuite, nous voulons peut-être obtenir une alerte lorsqu'une affectation comme $scope.board[0][1] = 7 le modifie.

champs de surveillance des objets

Peut-être plus utile que la surveillance de n'importe quel élément dans un tableau, nous pouvons surveiller n'importe quel champ dans un objet. Mais ce n'est pas surprenant, non? Après tout, un tableau dans JavaScript est un objet .

app.controller('watchDemoCtrl', ['$scope', function($scope){
    $scope.letters = ['A','B','C'];
}]);
Copier après la connexion
Copier après la connexion
Copier après la connexion

Quelle est la profondeur de la profondeur?

À ce stade, nous devons également clarifier un dernier détail mais crucial: que se passe-t-il si nous devons surveiller un objet imbriqué complexe où chaque champ est une valeur non primitive? Par exemple, un arbre ou un graphique, ou juste quelques données JSON.

Vérifions-le!

Tout d'abord, nous avons besoin d'un objet pour surveiller:

$scope.$watch('letters', function (newValue, oldValue, scope) {
    // 对 $scope.letters 执行任何操作
});
Copier après la connexion
Copier après la connexion
Copier après la connexion

Confirons le moniteur de l'ensemble de l'objet: je pense que jusqu'à présent, il est clair que dans ce cas, objectEquality doit être défini sur true.

$scope.$watch('letters', function (newValue, oldValue, scope) {
    // 对 $scope.letters 执行任何操作
}, true);
Copier après la connexion
Copier après la connexion

La question est: si des affectations comme $scope.b.bb[1].bb2a = 7; se produisent, Angular sera-t-il assez gentil pour nous le faire savoir?

La réponse est: oui, heureusement, elle le fera (voir dans la démo précédente de codepen).

Autres méthodes

$scope.$watchGroup

$watchGroup() Est-ce vraiment une approche différente? La réponse est non, ce n'est pas le cas.

$watchGroup() est un raccourci pratique qui vous permet de configurer plusieurs moniteurs en utilisant la même fonction de rappel et de passer un tableau de watchExpressions.

Chaque expression passée sera surveillée à l'aide de la méthode standard $scope.$watch().

$scope.$watch('letters[4]', function (newValue, oldValue, scope) {
    //...
}, true);
Copier après la connexion
Copier après la connexion

Il convient de noter que l'utilisation de $watchGroup, newValues et oldValues enregistrera la liste des valeurs de l'expression, y compris les valeurs qui ont changé et celles qui ont gardé la même valeur, dans L'ordre dans le premier paramètre L'ordre de passage dans le tableau est le même.

Si vous avez vérifié la documentation de cette méthode, vous remarquerez peut-être qu'elle ne prend pas l'option objectEquality. En effet, il surveille superficiellement les expressions et ne réagit que des changements de référence.

Si vous utilisez la démo $watchGroup() ci-dessous, vous pouvez être surpris par certaines subtilités. Par exemple, unshift entraînera l'appel de l'auditeur, au moins dans une certaine mesure: c'est parce que lors du passage de la liste d'expression à $watchGroup, tout déclenche une expression qui se traduira par une fonction de rappel d'exécution.

Exemple de codepen

également, notez que toute modification de tout sous-champ de

ne produira aucune mise à jour - les mises à jour ne seront générées que si une nouvelle valeur est attribuée au champ B lui-même. $scope.obj.b

$scope.$watchCollection

Il s'agit d'un autre raccourci pratique pour surveiller les tableaux ou les objets. Pour les tableaux, l'auditeur est appelé lorsqu'un élément est remplacé, supprimé ou ajouté. Pour les objets, lorsque des propriétés sont modifiées. Encore une fois,

ne permet pas $watchCollection(), de sorte qu'il ne surveille que des éléments / champs superficiels et ne réagit pas aux changements dans leurs sous-champs. objectEquality

Exemple de codepen

Conclusion

J'espère que ces exemples vous aideront à découvrir la puissance de cette caractéristique angulaire et à comprendre à quel point il est important d'utiliser les bonnes options.

N'hésitez pas à copier Codepen et essayez d'utiliser ces méthodes dans différents contextes et n'oubliez pas de laisser vos commentaires dans la section des commentaires!

Si vous voulez avoir un aperçu plus approfondi de certains des concepts dont nous avons discuté dans cet article, voici quelques suggestions pour une lecture plus approfondie:

    Scope angularjs
  1. comprendre Angular
  2. et $apply() $digest()
  3. Modèles émergents dans le traitement des événements JavaScript
  4. Héritage du prototype dans la portée angularjs
  5. Documents de
  6. etc. $watch

FAQS (FAQ) $watch Dans AngularJS

$watch Quel est le but principal dans AngularJS?

La fonction $watch dans AngularJS est principalement utilisée pour observer les changements dans la valeur d'une variable ou d'une expression. Il fait partie de l'objet portée AngularJS pour surveiller les changements dans la valeur d'une variable ou d'une expression. Lorsqu'un changement est détecté, la fonction $watch déclenche une fonction de rappel qui est exécutée chaque fois que la variable surveillée change.

$watch Comment cela fonctionne-t-il dans AngularJS?

La fonction $watch dans AngularJS fonctionne en comparant les valeurs anciennes et nouvelles de la variable ou de l'expression surveillée. Il utilise l'opérateur d'égalité de JavaScript (===) pour comparaison. Si la nouvelle valeur est différente de l'ancienne valeur, la fonction $watch déclenchera la fonction de rappel.

Comment utiliser $watch dans AngularJS?

Pour utiliser $watch dans AngularJS, vous devez appeler la méthode $watch sur l'objet Scope et la transmettre deux paramètres: le nom de la variable ou de l'expression à surveiller, et se produit lorsque la variable est surveillée le rappel fonction à exécuter lors du changement. Voici un exemple:

app.controller('watchDemoCtrl', ['$scope', function($scope){
    $scope.letters = ['A','B','C'];
}]);
Copier après la connexion
Copier après la connexion
Copier après la connexion
Quelle est la différence entre

$watch et $apply dans AngularJS?

La fonction

dans $watch dans angularjs est utilisée pour observer les changements dans les variables ou les expressions, tandis que la fonction $apply est utilisée pour démarrer manuellement la période de digestion angularjs, qui vérifie tout changement dans la variable surveillée et met à jour la vue par conséquent. La fonction $apply est généralement utilisée lors de la réalisation du modèle en dehors du contexte AngularJS, comme dans le gestionnaire d'événements DOM ou la fonction setTimeout.

Puis-je surveiller plusieurs variables dans AngularJS en utilisant $watch?

Oui, vous pouvez utiliser $watch pour surveiller plusieurs variables dans AngularJS. Vous pouvez le faire en passant un tableau de noms de variables à la fonction $watch. Cependant, n'oubliez pas que la surveillance des variables multiples peut affecter les performances, car la fonction $watch doit vérifier les modifications de toutes les variables surveillées dans chaque cycle de digestion.

Comment arrêter de surveiller les variables dans $watch dans AngularJS?

Lorsque vous appelez la fonction $watch dans angularjs, il renvoie une fonction de déconnexion. Vous pouvez appeler cette fonction pour arrêter de surveiller les variables. Voici un exemple:

$scope.$watch('letters', function (newValue, oldValue, scope) {
    // 对 $scope.letters 执行任何操作
});
Copier après la connexion
Copier après la connexion
Copier après la connexion

Qu'est-ce que $watchGroup dans AngularJS?

La fonction $watchGroup dans AngularJS est utilisée pour surveiller un ensemble d'expressions. Il fonctionne comme la fonction $watch, mais il déclenche la fonction de rappel une seule fois par cycle de digestion, même si plusieurs expressions surveillées changent. Cela peut améliorer les performances lors du suivi de plusieurs expressions.

Qu'est-ce que $watchCollection dans AngularJS?

La fonction $watchCollection dans AngularJS est utilisée pour surveiller les attributs d'un objet ou des éléments d'un tableau. Il déclenche la fonction de rappel tant que tout attribut ou élément change, mais contrairement à $watch, il ne surveille pas profondément des objets ou des tableaux, ce qui peut améliorer les performances.

Puis-je utiliser $watch dans la directive AngularJS?

Oui, vous pouvez utiliser $watch dans la directive AngularJS. En fait, il est courant d'utiliser $watch dans les directives pour répondre aux changements dans les attributs ou les variables de portée des directives.

Quelles sont les considérations de performance dans AngularJS en utilisant $watch?

L'utilisation de $watch dans AngularJS peut affecter les performances, en particulier lors de la surveillance de nombreuses variables ou expressions. En effet, la fonction $watch doit vérifier les modifications de toutes les variables surveillées dans chaque cycle de digestion. Pour améliorer les performances, envisagez d'utiliser $watchGroup ou $watchCollection en fonction de la situation ou limitez le nombre de variables surveillées.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal