Points de base
$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. $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. $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']
;
$scope.$watch('letters', function () {...});
déclenchera-t-il sa fonction de rappel? $scope.$watch('letters[0]', function () {...});
? Cela fonctionnera-t-il de la même manière, ou est-ce mieux? $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
.
$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 à:
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
.
Regardons le code de $rootscope.watch()
.
C'est sa signature: function(watchExp, listener, objectEquality, prettyPrintExpression)
.
En détail, ses quatre paramètres:
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.
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.
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.
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:
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.
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']; }]);
Une option consiste à utiliser un appel comme ceci:
$scope.$watch('letters', function (newValue, oldValue, scope) { // 对 $scope.letters 执行任何操作 });
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
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);
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
, 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
comme premier argument: $watch
$scope.$watch('letters[4]', function (newValue, oldValue, scope) { //... }, true);
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:
objectEquality
. $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. 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']; }]);
À 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 执行任何操作 });
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);
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);
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.
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
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
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:
$apply()
$digest()
$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.
$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']; }]);
$watch
et $apply
dans AngularJS? 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
.
$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.
$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 执行任何操作 });
$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.
$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.
$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.
$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!