Lorsque vous soumettez un formulaire dans AngularJS et utilisez la fonctionnalité de mémorisation du mot de passe du navigateur, et lors d'une tentative de connexion ultérieure, vous laissez le navigateur remplir le formulaire de connexion avec le nom d'utilisateur et le mot de passe, le $scope
modèle ne sera pas modifié en fonction de la saisie automatique.
Le seul hack sale que j'ai trouvé est d'utiliser la directive suivante:
app.directive("xsInputSync", ["$timeout" , function($timeout) {
return {
restrict : "A",
require: "?ngModel",
link : function(scope, element, attrs, ngModel) {
$timeout(function() {
if (ngModel.$viewValue && ngModel.$viewValue !== element.val()) {
scope.apply(function() {
ngModel.$setViewValue(element.val());
});
}
console.log(scope);
console.log(ngModel.$name);
console.log(scope[ngModel.$name]);
}, 3000);
}
};
}]);
Le problème est que le ngModel.$setViewValue(element.val());
ne modifie pas le modèle ni la vue en fonction de la element.val()
valeur renvoyée. Comment puis-je y parvenir?
javascript
mvvm
angularjs
lucassp
la source
la source
Réponses:
Apparemment, il s'agit d'un problème connu avec Angular et est actuellement ouvert
Je ne sais pas ce que vous pourriez faire ici en plus d'une sorte de travail comme vous essayez. Il semble que vous êtes sur la bonne voie. Je n'ai pas pu faire en sorte que mon navigateur essaie de se souvenir d'un mot de passe pour votre plunk, donc je ne suis pas sûr que cela fonctionnera, mais jetez un œil:
Je pense que vous avez juste besoin de simplifier un peu votre approche. La seule chose que je recommande vraiment est de vérifier
ngModel.$pristine
et de vous assurer que vous n'écrasez pas les entrées d'un utilisateur médiocre. De plus, 3 secondes, c'est probablement trop long. Vous ne devriez pas avoir à appeler $ apply () dans un $ timeout, BTW, il devrait mettre en file d'attente un $ digest pour vous automatiquement.Le vrai hic: votre navigateur battra-t-il Angular à l'exécution? Et mon navigateur?
C'est probablement une guerre impossible à gagner, c'est pourquoi Angular (ou Knockout) n'a pas été en mesure de la résoudre facilement. Il n'y a aucune garantie de l'état des données dans votre entrée au moment de l'exécution initiale de la directive. Pas même au moment de l'initialisation d'Angular ... C'est donc un problème délicat à résoudre.
la source
Voici une solution beaucoup moins hacky que les autres solutions présentées et qui est sémantiquement saine AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/
Ensuite, vous attachez simplement la directive à votre formulaire:
la source
Vous n'avez pas besoin d'utiliser un
$timeout
ou quelque chose comme ça. Vous pouvez utiliser un système d'événements.Je pense que c'est plus angulaire et ne dépend pas de jQuery ou de la capture d'événements personnalisés.
Par exemple sur votre gestionnaire d'envoi:
Et puis vous pouvez avoir une
autofill
directive comme celle-ci:Enfin, votre HTML sera comme:
la source
Plus besoin de pirater! Angular dev tbosch a créé un polyfill qui déclenche un événement de modification lorsque le navigateur modifie les champs du formulaire sans déclencher d'événement de modification:
https://github.com/tbosch/autofill-event
Pour l'instant, ils ne l'intégreront pas dans le code Angular, car il s'agit d'un correctif pour le navigateur, et fonctionne également sans Angular (par exemple pour les applications jQuery simples).
"Le polyfill vérifiera les modifications lors du chargement du document et également lorsqu'une entrée est laissée (uniquement sous la même forme). Cependant, vous pouvez déclencher la vérification manuellement si vous le souhaitez.
Le projet comporte des tests unitaires ainsi que des tests semi-automatiques, nous avons donc enfin un endroit pour collecter tous les différents cas d'utilisation avec les paramètres de navigateur requis.
Remarque: ce polyfill fonctionne avec les applications AngularJS simples, avec les applications AngularJS / jQuery mais aussi avec les applications jQuery simples qui n'utilisent pas Angular. "
Il peut être installé avec:
Ajoutez le script
autofill-event.js
après jQuery ou Angular dans votre page.Cela fera ce qui suit:
API (pour déclencher manuellement la vérification):
$el.checkAndTriggerAutoFillEvent()
: Exécute la vérification de tous les éléments DOM dans l'élément jQuery / jQLite donné.Comment ça fonctionne
Souvenez-vous de toutes les modifications apportées aux éléments d'entrée par l'utilisateur (à l'écoute des événements de modification) et également par JavaScript (en interceptant $ el.val () pour les éléments jQuery / jQLite). Cette valeur modifiée est stockée sur l'élément dans une propriété privée.
Vérification d'un élément pour le remplissage automatique: Comparez la valeur actuelle de l'élément avec la valeur mémorisée. Si c'est différent, déclenchez un événement de modification.
Dépendances
AngularJS ou jQuery (fonctionne avec l'un ou les deux)
Plus d'informations et source sur la page github .
Le problème angulaire original n ° 1460 sur Github peut être lu ici.
la source
ngModelOptions
combiné avecautofill-event
signifie que vous pouvez désormais le spécifierchange
comme l'un desupdateOn
événements pour vous assurer que votre modèle est correctement synchronisé.Code sale, vérifiez si le problème https://github.com/angular/angular.js/issues/1460#issuecomment-18572604 est résolu avant d'utiliser ce code. Cette directive déclenche des événements lorsque le champ est rempli, pas seulement avant de soumettre (c'est nécessaire si vous devez gérer l'entrée avant de soumettre)
la source
Cela ressemble à une solution claire et directe. Aucun jQuery nécessaire.
METTRE À JOUR:
la source
$pristine
avant de le changer, puis après l'avoir changé, conserver son$pristine
état. Sinon, vous constaterez que si un formulaire est chargé sans données de remplissage automatique, la directive ci-dessus mettra toujours à jour le modèle et le rendra par la suitedirty
même si le contrôle de formulaire doit toujours être considéré comme intact. exemple ici, en utilisant votre directive. J'ai commenté le code que j'ajouterais: jsfiddle.net/OACDesigns/L8Sja/4scope:true
devrait êtrescope:{}
Solution 1 [Utilisation de $ timeout]:
Directif:
HTML:
Solution 2 [Utilisation d'événements angulaires]:
Réf: réponse de Becko
Directif:
HTML:
Solution 3 [Utilisation des appels de méthode de relais]:
Directif:
HTML:
la source
model.$valid
de la directive renvoie vrai avant et après$setViewValue
, mais l'élément est toujours avec lang-invalid
classeEh bien, le moyen le plus simple est d'émuler le comportement du navigateur, donc s'il y a un problème avec l'événement de changement, lancez-le vous-même. Beaucoup plus simple.
Directif:
HTML:
Vous pouvez faire quelques variantes, comme mettre la directive sur le formulaire et déclencher l'événement sur toutes les entrées avec la classe .dirty lors de la soumission du formulaire.
la source
C'est la manière jQuery:
C'est la manière angulaire:
HTML
la source
triggerHandler('input')
devrait être ok si vous n'avez pas jquery completVoici une autre solution de contournement qui est moins piratée, mais nécessite du code supplémentaire dans le contrôleur.
HTML:
Directive (CoffeeScript):
Manette:
la source
C'est la seule solution que j'ai trouvée qui a permis à toutes mes validations Angular de fonctionner comme prévu, y compris la désactivation / l'activation du bouton d'envoi. S'installe avec bower et 1 balise de script. Bazinga!
https://github.com/tbosch/autofill-event
la source
Changer la valeur du modèle au lieu d'utiliser une fonction de délai d'expiration a fonctionné pour moi.
Voici mon code:
la source
Solution de contournement en une ligne dans le gestionnaire de soumission (nécessite jQuery):
la source
Je force un $ setValue (val ()) lors de la soumission: (cela fonctionne sans jQuery)
la source
Je suis très nouveau sur Angularjs, mais j'ai trouvé une solution simple à ce problème => Forcer Angular à réévaluer l'expression ... en la changeant! (bien sûr, vous devez vous souvenir de la valeur initiale pour revenir à l'état initial) Voici comment cela se passe dans la fonction de votre contrôleur pour soumettre le formulaire:
où bien sûr, la valeur entrée dans votre saisie de mot de passe a été définie par Windows et non par l'utilisateur.
la source
Vous pouvez essayer ce code:
la source
Une modification mineure à cette réponse ( https://stackoverflow.com/a/14966711/3443828 ): utilisez un $ intervalle au lieu d'un $ timeout pour ne pas avoir à courir le navigateur.
la source
C'est la solution que j'ai fini par utiliser dans mes formulaires.
Et le modèle du formulaire sera
De cette façon, j'ai pu exécuter tous les analyseurs / formateurs que j'ai sur mon ng-model et avoir la fonctionnalité d'envoi transparente.
la source
Solution sans directives:
la source
Il s'agit d'une solution simple qui fonctionne pour tous les cas que j'ai testés à la fois dans Firefox et Chrome. Notez qu'avec la première réponse (directive w / timeout), j'ai eu des problèmes avec -
Ce correctif est évidemment très stupide et piraté, mais cela fonctionne 100% du temps -
la source
$timeout
par$interval
pour donner un peu plus de contexte aux futurs développeurs et se débarrasser des appels récursifs étranges qui s'yAucune de ces solutions n'a fonctionné pour mon cas d'utilisation. J'ai quelques champs de formulaire qui utilisent ng-change pour surveiller les changements. L'utilisation
$watch
n'est d'aucune aide car elle n'est pas déclenchée par la saisie automatique. Comme je n'ai pas de bouton d'envoi, il n'y a pas de moyen facile d'exécuter certaines des solutions et je n'ai pas réussi à utiliser les intervalles.J'ai fini par désactiver le remplissage automatique - pas idéal mais beaucoup moins déroutant pour l'utilisateur.
J'ai trouvé la réponse ici
la source
Si vous utilisez jQuery, vous pouvez le faire en soumettant le formulaire:
HTML:
JS:
la source
Si vous voulez rester simple, obtenez simplement la valeur en utilisant javascript
Dans votre contrôleur angular js:
var username = document.getElementById ('username'). value;
la source