Maison >interface Web >js tutoriel >notes d'étude angulaire1, qui contiennent le processus de synchronisation du modèle de vue dans angulairejs
Ceci est une note de compréhension personnelle de angularjs Voici le processus de synchronisation du modèle de vue. Laissez-moi l'écrire pour que tout le monde puisse le voir
. Le problème vient d'un petit problème rencontré dans le projet : le projet nécessite une zone de saisie pour saisir la quantité de produits vendus, et les frais de traitement sont calculés sur la base des données saisies après les saisies de l'utilisateur. Naturellement, j'ai utilisé ng-model et ng-change, et généralement il n'y a aucun problème. Le problème est le suivant : il y a un bouton sous la zone de saisie pour tout vendre. Cliquer sur ce bouton définira automatiquement le montant de la vente. Mais en fait, le programme ne calcule pas les frais de traitement pour le moment.
Après dépannage et consultation de la documentation, j'ai découvert qu'il s'agissait d'un problème avec ng-change. Le document officiel d'Angular sur ng-change demande :
L'expression n'est pas évaluée lorsque le changement de valeur provient du modèle.
Le code source de ng-change est également très simple :
var ngChangeDirective = valueFn({ restrict: 'A', require: 'ngModel', link: function(scope, element, attr, ctrl) { ctrl.$viewChangeListeners.push(function() { scope.$eval(attr.ngChange); }); } });
Nous pouvons également voir que ng-change surveille uniquement la vue du modèle. Ainsi, lorsque nous modifions les variables de ng-model directement dans js, ng-change ne sera pas déclenché.
Le problème est trouvé et la solution n'est pas difficile. Abandonnez simplement ng-change et utilisez $watch à la place.
Mais est-ce fini ? Que traverse exactement une variable depuis le changement de vue jusqu'à la mise à jour synchrone du modèle ? Dans l'autre sens, c'est pareil ?
J'ai donc jeté un nouveau coup d'œil au code source de ng-model et je n'ai rien trouvé, mais j'ai appris ceci de manière inattendue :
ng-change est exécuté avant que la valeur du modèle ne change. Il existe une telle fonction dans le code source de ng-model :
function setupModelWatcher(ctrl) { // model -> value // !!!Note: we cannot use a normal scope.$watch as we want to detect the following: // !!!1. scope value is 'a' // !!! 2. user enters 'b' // !!!3. ng-change kicks in and reverts scope value to 'a' // -> scope value did not change since the last digest as // ng-change executes in apply phase // !!!4. view should be changed back to 'a' ctrl.$$scope.$watch(function ngModelWatch(scope) { var modelValue = ctrl.$$ngModelGet(scope); // if scope model value and ngModel value are out of sync // This cannot be moved to the action function, because it would not catch the // case where the model is changed in the ngChange function or the model setter if (modelValue !== ctrl.$modelValue && // checks for NaN is needed to allow setting the model to NaN when there's an asyncValidator // eslint-disable-next-line no-self-compare (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue) ) { ctrl.$$setModelValue(modelValue); } return modelValue; }); }
Les commentaires à l'intérieur expliquent pourquoi la valeur du modèle variable doit être modifiée après ng-change, car ng-change est susceptible de changer la valeur de la variable à nouveau. Modifiez-la à nouveau pour que la valeur de la variable n'ait pas réellement changé (vous devez vraiment prendre en compte toutes les situations lors de l'écriture d'une API !!). Concernant cette question et la précédente, voici un code de démonstration : http://php.cn/course/47.html
Puisqu'il n'y a rien à gagner à regarder le code source, alors partez chercher des articles en ligne. Au cours de ce processus, j'ai trouvé un bon article, qui présentait
$formatters
, $parsers
, $render
et $setViewValue
. Je ne le présenterai plus ici Si vous avez besoin d'apprendre, le texte original est ici : http://php.cn/course/47.html
Pendant mes études$setViewValue
, j'ai aussi trouvé un point facile à tromper : lors de l'appel de $setViewValue
, si le paramètre est une variable de référence, alors si l'adresse de la variable de référence n'a pas changé, la variable est considérée comme inchangée, comme var map = ['er', 'tr ']; then map.pop(); Après cela, $setViewValue ne pense pas que la valeur de la carte a changé. Pour plus de détails à ce sujet, veuillez consulter ma réponse à cette question. (Si vous voulez en savoir plus, rendez-vous sur le site Web PHP chinois Manuel de développement AngularJS pour en savoir)
ng-model a également ce problème, qui peut être vu dans la source ng-model commentaires du code :
Cependant, les contrôles personnalisés peuvent également transmettre des objets à cette méthode. Dans
ce cas, nous devons faire une copie de l'objet avant de le transmettre à$setViewValue
. En effet,ngModel
n'effectue pas une surveillance approfondie
des objets, il recherche uniquement un changement d'identité.Si vous modifiez uniquement la propriété de l'objet, alors ngModel ne
se rendra compte que l'objet a changé et n'invoquera pas les pipelines$parsers
et$validators
.
Vous pouvez également voir de ce qui précède que la mise à jour d'une variable de la vue au modèle et du modèle à la vue est plus que les pipelines $formatters
et $parsers
, alors qu'y a-t-il d'autre ?
Après avoir vérifié de nombreuses informations, j'ai trouvé une explication très claire : https://stackoverflow.com/que... En fait, il suffit de lire la réponse à la question. long. . .
Il y a un lien de démonstration dans cette réponse. Je l'ai copié et apporté de petites modifications et je l'ai mis à cette adresse : http://php.cn/course/47.html Cette démo montre clairement le processus de mise à jour des variables. ne sera pas répété en détail. Ici, nous résumons uniquement les résultats comme suit :
Du modèle à la vue :
Modification de la valeur du modèle----$formatters
Pipeline----> ----> $render
----> $validators
Fonction$watch
afficher la modification de la valeur----> >
Pipeline----> $setViewValue
----> $parsers
Fonction----> $validators
Fonction$viewChangeListener
Nous pouvons également appeler directement la fonction $watch
Changer directement la valeur de
et le processus seront les mêmes que ci-dessus. $setViewValue
Notez que lors de l'utilisation de $viewValue
, vous devez vous méfier des paramètres qui font référence à des variables. Cet écueil a également été évoqué ci-dessus. $setViewValue
Cet article ne présente pas spécifiquement les pipelines
Pour cette partie, vous pouvez vous référer au lien $formatters
donné dans l'article.
D'accord, cet article se termine ici (si vous voulez en savoir plus, rendez-vous sur le site Web PHP chinois Manuel d'utilisation d'AngularJS pour en savoir plus). Si vous avez des questions, vous pouvez laisser un message ci-dessous.
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!