Al enviar un formulario en AngularJS y usar la funcionalidad de recordar contraseña del navegador, y en un intento de inicio de sesión posterior, deja que el navegador complete el formulario de inicio de sesión con el nombre de usuario y la contraseña, el $scope
modelo no se cambiará según el autocompletado.
El único truco sucio que encontré es usar la siguiente directiva:
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);
}
};
}]);
El problema es que ngModel.$setViewValue(element.val());
no cambia el modelo ni la vista en función del element.val()
valor devuelto. ¿Cómo puedo lograrlo?
javascript
mvvm
angularjs
lucassp
fuente
fuente
Respuestas:
Aparentemente, este es un problema conocido con Angular y actualmente está abierto
No estoy seguro de qué podrías hacer aquí además de algún tipo de trabajo como lo estás intentando. Parece que estás en el camino correcto. No pude hacer que mi navegador intentara recordar una contraseña para su plunk, así que no estoy seguro de si esto funcionará, pero eche un vistazo:
Creo que solo necesitas simplificar un poco tu enfoque. Lo único que definitivamente recomiendo es verificar
ngModel.$pristine
y asegurarse de no sobrescribir la entrada de un usuario deficiente. Además, 3 segundos probablemente sea demasiado tiempo. No debería tener que llamar a $ apply () en un $ timeout, por cierto, debería poner en cola un $ digest automáticamente.La verdadera trampa: ¿Su navegador superará a Angular en la ejecución? ¿Y mi navegador?
Esta es probablemente una guerra imposible de ganar, por lo que Angular (o Knockout) no ha podido resolverla fácilmente. No hay garantía del estado de los datos en su entrada en el momento de la ejecución inicial de la directiva. Ni siquiera en el momento de la inicialización de Angular ... Así que es un problema complicado de resolver.
fuente
Aquí hay una solución que es mucho menos hacky que otras soluciones presentadas y es semánticamente sólida AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/
Luego, simplemente adjunte la directiva a su formulario:
fuente
No tienes que usar un
$timeout
ni nada parecido. Puede utilizar un sistema de eventos.Creo que es más angular y no depende de jQuery o de la captura de eventos personalizados.
Por ejemplo, en su controlador de envío:
Y luego puedes tener una
autofill
directiva como esta:Finalmente, su HTML será como:
fuente
¡Ya no es necesario piratear! Angular dev tbosch hizo un polyfill que desencadena un evento de cambio cuando el navegador cambia los campos de formulario sin desencadenar un evento de cambio:
https://github.com/tbosch/autofill-event
Por ahora, no integrarán esto en el código Angular, ya que es una corrección de errores para el navegador y también funciona sin Angular (por ejemplo, para aplicaciones jQuery simples).
"El polyfill comprobará los cambios en la carga del documento y también cuando se deje una entrada (solo en el mismo formulario). Sin embargo, puede activar la comprobación manualmente si lo desea.
El proyecto tiene pruebas unitarias y pruebas semiautomáticas, por lo que finalmente tenemos un lugar para recopilar todos los casos de uso diferentes junto con la configuración requerida del navegador.
Tenga en cuenta: este polyfill funciona con aplicaciones simples de AngularJS, con aplicaciones de AngularJS / jQuery, pero también con aplicaciones simples de jQuery que no usan Angular ".
Se puede instalar con:
Agregue el script
autofill-event.js
después de jQuery o Angular en su página.Esto hará lo siguiente:
API (para activar manualmente la verificación):
$el.checkAndTriggerAutoFillEvent()
: Ejecute la comprobación de todos los elementos DOM en el elemento jQuery / jQLite dado.Cómo funciona
Recuerde todos los cambios en los elementos de entrada por parte del usuario (escuchando eventos de cambio) y también por JavaScript (interceptando $ el.val () para los elementos jQuery / jQLite). Ese valor modificado se almacena en el elemento en una propiedad privada.
Verificación de un elemento para autocompletar: Compare el valor actual del elemento con el valor recordado. Si es diferente, active un evento de cambio.
Dependencias
AngularJS o jQuery (funciona con uno o ambos)
Más información y fuente en la página de github .
El número original de Angular # 1460 en Github se puede leer aquí.
fuente
ngModelOptions
combinado conautofill-event
medios que ahora puede especificarchange
como uno de losupdateOn
eventos para asegurarse de que su modelo esté sincronizado correctamente.Código sucio, verifique si el problema https://github.com/angular/angular.js/issues/1460#issuecomment-18572604 está solucionado antes de usar este código. Esta directiva desencadena eventos cuando se completa el campo, no solo antes del envío (es necesario si tiene que manejar la entrada antes de enviar)
fuente
Parece una solución clara y recta. No se necesita jQuery.
ACTUALIZAR:
fuente
$pristine
antes de cambiarlo, y luego, después de cambiarlo, mantener su$pristine
estado. De lo contrario, encontrará que si un formulario se carga sin datos de autocompletar, la directiva anterior aún actualizará el modelo y, posteriormente, lo harádirty
a pesar de que el control del formulario aún debe considerarse intacto. ejemplo aquí, usando su directiva. He comentado el código que le agregaría: jsfiddle.net/OACDesigns/L8Sja/4scope:true
debería serscope:{}
Solución 1 [Uso de $ timeout]:
Directiva:
HTML:
Solución 2 [Uso de eventos angulares]:
Ref: respuesta de Becko
Directiva:
HTML:
Solución 3 [Uso de llamadas al método de retransmisión]:
Directiva:
HTML:
fuente
model.$valid
de la directiva devuelve verdadero antes y después$setViewValue
, pero el elemento todavía está con lang-invalid
claseBueno, la forma más fácil es emular el comportamiento del navegador, así que si hay un problema con el evento de cambio, simplemente enciéndalo usted mismo. Mucho más simple.
Directiva:
HTML:
Puede hacer algunas variaciones, como poner la directiva en el formulario y activar el evento en todas las entradas con la clase .dirty en el envío del formulario.
fuente
Esta es la forma jQuery:
Esta es la forma angular:
HTML
fuente
triggerHandler('input')
debería estar bien si no tiene jquery completoAquí hay otra solución que es menos intrincada, pero requiere algo de código adicional en el controlador.
HTML:
Directiva (CoffeeScript):
Controlador:
fuente
Esta es la única solución que he encontrado que permitió que todas las validaciones de mi Angular funcionaran según lo diseñado, incluida la desactivación / activación del botón de envío. Se instala con bower y 1 etiqueta de script. ¡Bazinga!
https://github.com/tbosch/autofill-event
fuente
Cambiar el valor del modelo, en lugar de usar una función de tiempo de espera funcionó para mí.
Aquí está mi código:
fuente
Solución alternativa de una sola línea en el controlador de envío (requiere jQuery):
fuente
Obligo un $ setValue (val ()) al enviar: (esto funciona sin jQuery)
fuente
Soy muy nuevo en Angularjs, pero encontré una solución simple a ese problema => Forzar Angular para reevaluar la expresión ... ¡cambiándola! (por supuesto, debe recordar el valor inicial para volver al estado inicial) Esta es la forma en que funciona en la función de su controlador para enviar el formulario:
donde, por supuesto, el valor ingresado en la entrada de su contraseña ha sido establecido por Windows y no por el usuario.
fuente
Puedes probar este código:
fuente
Una pequeña modificación a esta respuesta ( https://stackoverflow.com/a/14966711/3443828 ): use un $ interval en lugar de un $ timeout para que no tenga que competir con el navegador.
fuente
Esta es la solución que terminé usando en mis formularios.
Y la plantilla del formulario será
De esta manera, pude ejecutar cualquier analizador / formateador que tenga en mi modelo ng y tener la funcionalidad de envío transparente.
fuente
Solución sin directivas:
fuente
Esta es una solución simple que funciona para todos los casos que he probado tanto en Firefox como en Chrome. Tenga en cuenta que con la respuesta principal (directiva sin tiempo de espera) tuve problemas con:
Esta solución es obviamente muy tonta y hack, pero funciona el 100% del tiempo.
fuente
$timeout
con$interval
para dar a los futuros desarrolladores un poco más de contexto y deshacerse de las llamadas recursivas de aspecto extraño queNinguna de estas soluciones funcionó para mi caso de uso. Tengo algunos campos de formulario que usan ng-change para observar el cambio. Utilizando
$watch
no ayuda, ya que no se activa mediante el autocompletado. Como no tengo un botón de envío, no hay una manera fácil de ejecutar algunas de las soluciones y no tuve éxito al usar intervalos.Terminé deshabilitando la función de autocompletar; no es lo ideal, pero es mucho menos confuso para el usuario.
Encontré la respuesta aquí
fuente
Si está utilizando jQuery, puede hacer esto en el envío del formulario:
HTML:
JS:
fuente
Si desea mantenerlo simple, obtenga el valor usando javascript
En su controlador angular js:
var username = document.getElementById ('nombre de usuario'). valor;
fuente