Wenn Sie ein Formular in AngularJS senden und die Browser-Funktion $scope
zum Speichern des Kennworts verwenden und bei einem nachfolgenden Anmeldeversuch den Browser das Anmeldeformular mit dem Benutzernamen und dem Kennwort ausfüllen lassen, wird das Modell nicht basierend auf dem automatischen Ausfüllen geändert.
Der einzige schmutzige Hack, den ich gefunden habe, ist die Verwendung der folgenden Anweisung:
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);
}
};
}]);
Das Problem ist, dass ngModel.$setViewValue(element.val());
weder das Modell noch die Ansicht basierend auf dem element.val()
zurückgegebenen Wert geändert werden. Wie kann ich das erreichen?
javascript
mvvm
angularjs
lucassp
quelle
quelle
Antworten:
Anscheinend ist dies ein bekanntes Problem mit Angular und ist derzeit offen
Ich bin mir nicht sicher, was Sie hier tun könnten, abgesehen von irgendeiner Art von Arbeit, wie Sie es versuchen. Sie scheinen auf dem richtigen Weg zu sein. Ich konnte meinen Browser nicht dazu bringen, sich ein Passwort für Ihren Plunk zu merken, daher bin ich mir nicht sicher, ob dies funktionieren wird, aber schauen Sie sich Folgendes an:
Ich denke, Sie müssen Ihren Ansatz nur ein wenig vereinfachen. Das einzige, was ich auf jeden Fall empfehlen kann, ist zu überprüfen
ngModel.$pristine
, ob Sie die Eingaben eines schlechten Benutzers nicht überschreiben. Auch 3 Sekunden sind wahrscheinlich zu lang. Sie sollten $ apply () nicht in einem $ timeout aufrufen müssen, übrigens sollte es automatisch einen $ Digest für Sie in die Warteschlange stellen.Der wahre Haken: Wird Ihr Browser Angular bei der Ausführung schlagen? Was ist mit meinem Browser?
Dies ist wahrscheinlich ein nicht gewinnbarer Krieg, weshalb Angular (oder Knockout) ihn nicht ohne weiteres lösen konnte. Es gibt keine Garantie für den Status der Daten in Ihrer Eingabe zum Zeitpunkt der ersten Ausführung der Richtlinie. Nicht einmal zum Zeitpunkt der Initialisierung von Angular ... Es ist also ein schwieriges Problem, es zu lösen.
quelle
Hier ist eine Lösung, die weitaus weniger hackig ist als andere vorgestellte Lösungen und semantisch einwandfrei ist. AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/
Dann fügen Sie einfach die Direktive Ihrem Formular bei:
quelle
Sie müssen kein
$timeout
oder ähnliches verwenden. Sie können ein Ereignissystem verwenden.Ich denke, es ist eher angularisch und hängt nicht von jQuery oder benutzerdefiniertem Ereignisfang ab.
Zum Beispiel auf Ihrem Submit-Handler:
Und dann können Sie eine
autofill
Anweisung wie diese haben:Schließlich wird Ihr HTML wie folgt aussehen:
quelle
Sie müssen nicht mehr hacken! Angular Dev Tbosch hat eine Polyfüllung erstellt, die ein Änderungsereignis auslöst, wenn der Browser Formularfelder ändert, ohne ein Änderungsereignis auszulösen:
https://github.com/tbosch/autofill-event
Im Moment wird dies nicht in den Angular-Code integriert, da dies ein Bugfix für den Browser ist und auch ohne Angular funktioniert (z. B. für einfache jQuery-Apps).
"Die Polyfüllung prüft beim Laden von Dokumenten und auch dann, wenn eine Eingabe übrig bleibt (nur in derselben Form), auf Änderungen. Sie können die Prüfung jedoch manuell auslösen, wenn Sie möchten.
Das Projekt umfasst sowohl Komponententests als auch halbautomatische Tests, sodass wir endlich die Möglichkeit haben, die verschiedenen Anwendungsfälle zusammen mit den erforderlichen Browsereinstellungen zu erfassen.
Bitte beachten Sie: Diese Polyfüllung funktioniert mit einfachen AngularJS-Apps, mit AngularJS / jQuery-Apps, aber auch mit einfachen jQuery-Apps, die Angular nicht verwenden. "
Es kann installiert werden mit:
Fügen Sie das Skript
autofill-event.js
nach hinzu jQuery oder Angular zu Ihrer Seite hinzu.Dies wird Folgendes bewirken:
API (um die Prüfung manuell auszulösen):
$el.checkAndTriggerAutoFillEvent()
: Führen Sie die Prüfung für alle DOM-Elemente im angegebenen jQuery / jQLite-Element aus.Wie es funktioniert
Merken Sie sich alle Änderungen an Eingabeelementen durch den Benutzer (auf Änderungsereignisse achten) und auch durch JavaScript (durch Abfangen von $ el.val () für jQuery / jQLite-Elemente). Dieser geänderte Wert wird auf dem Element in einer privaten Eigenschaft gespeichert.
Überprüfen eines Elements auf automatische Füllung: Vergleichen Sie den aktuellen Wert des Elements mit dem gespeicherten Wert. Wenn es anders ist, lösen Sie ein Änderungsereignis aus.
Abhängigkeiten
AngularJS oder jQuery (funktioniert mit einem oder beiden)
Weitere Infos und Quelle auf der Github-Seite .
Die Original Angular Issue # 1460 auf Github kann hier gelesen werden.
quelle
ngModelOptions
kombiniert mitautofill-event
Mitteln, die Sie jetztchange
als eines derupdateOn
Ereignisse angeben können, um sicherzustellen, dass Ihr Modell korrekt synchronisiert ist.Überprüfen Sie, ob das Problem https://github.com/angular/angular.js/issues/1460#issuecomment-18572604 behoben ist, bevor Sie diesen Code verwenden. Diese Anweisung löst Ereignisse aus, wenn das Feld gefüllt ist, nicht nur vor dem Senden (dies ist erforderlich, wenn Sie die Eingabe vor dem Senden verarbeiten müssen).
quelle
Scheint eine klare, geradlinige Lösung zu sein. Keine jQuery erforderlich.
AKTUALISIEREN:
quelle
$pristine
bevor Sie es ändern, und dann nach dem Ändern den$pristine
Status beizubehalten. Andernfalls werden Sie feststellen, dass die obige Anweisung das Modell weiterhin aktualisiert und anschließend erstellt, wenn ein Formular ohne Daten zum automatischen Ausfüllen geladen wirddirty
, obwohl das Formularsteuerelement weiterhin als unberührt betrachtet werden sollte. Beispiel hier mit Ihrer Direktive. Ich habe den Code auskommentiertscope:true
sein solltescope:{}
Lösung 1 [Verwenden von $ timeout]:
Richtlinie:
HTML:
Lösung 2 [Verwenden von Winkelereignissen]:
Ref: Beckos Antwort
Richtlinie:
HTML:
Lösung 3 [Verwenden von Relay-Methodenaufrufen]:
Richtlinie:
HTML:
quelle
model.$valid
Direktive gibt sowohl vorher als auch nachher true zurück$setViewValue
, aber das Element ist immer noch in derng-invalid
KlasseAm einfachsten ist es, das Verhalten des Browsers zu emulieren. Wenn also ein Problem mit dem Änderungsereignis auftritt, lösen Sie es einfach selbst aus. Viel einfacher.
Richtlinie:
HTML:
Sie können einige Variationen ausführen, z. B. die Anweisung in das Formular einfügen und das Ereignis für alle Eingaben mit der Klasse .dirty beim Senden des Formulars auslösen.
quelle
Dies ist jQuery Weg:
Dies ist Angular Weg:
HTML
quelle
triggerHandler('input')
sollte in Ordnung sein, wenn Sie nicht ausgewachsene jquery habenHier ist eine weitere Problemumgehung, die weniger hackig ist, aber zusätzlichen Code im Controller erfordert.
HTML:
Richtlinie (CoffeeScript):
Regler:
quelle
Dies ist die einzige Lösung, die es mir ermöglicht hat, dass alle meine Angular-Validierungen wie geplant funktionieren, einschließlich der Schaltfläche zum Deaktivieren / Aktivieren der Übermittlung. Wird mit Laube und 1 Skript-Tag installiert. Bazinga!
https://github.com/tbosch/autofill-event
quelle
Das Ändern des Modellwerts anstelle einer Timeout-Funktion hat bei mir funktioniert.
Hier ist mein Code:
quelle
Einzeilige Problemumgehung im Submit-Handler (erfordert jQuery):
quelle
Ich erzwinge beim Senden einen $ setValue (val ()): (dies funktioniert ohne jQuery)
quelle
Ich bin sehr neu in Angularjs, aber ich habe eine einfache Lösung für dieses Problem gefunden => Angular zwingen, den Ausdruck neu zu bewerten ... indem ich ihn ändere! (Natürlich müssen Sie sich den Anfangswert merken, um zum Ausgangszustand zurückzukehren.) So geht es in Ihrer Controller-Funktion zum Senden des Formulars:
Dabei wurde der in Ihre Passworteingabe eingegebene Wert natürlich von Windows und nicht vom Benutzer festgelegt.
quelle
Sie können diesen Code ausprobieren:
quelle
Eine geringfügige Änderung dieser Antwort ( https://stackoverflow.com/a/14966711/3443828 ): Verwenden Sie ein $ -Intervall anstelle eines $ -Zeitlimits, damit Sie nicht mit dem Browser rennen müssen.
quelle
Dies ist die Lösung, die ich letztendlich in meinen Formularen verwendet habe.
Und die Vorlage des Formulars wird sein
Auf diese Weise konnte ich alle Parser / Formatierer ausführen, die ich auf meinem ng-Modell habe, und die Übermittlungsfunktion transparent machen.
quelle
Lösung ohne Richtlinien:
quelle
Dies ist eine einfache Lösung, die für alle Fälle funktioniert, die ich sowohl in Firefox als auch in Chrome getestet habe. Beachten Sie, dass ich mit der Top-Antwort (Direktive mit Timeout) Probleme mit - hatte
Dieses Update ist offensichtlich sehr dumm und hackig, aber es funktioniert 100% der Zeit -
quelle
$timeout
werden$interval
, um zukünftigen Entwicklern ein bisschen mehr Kontext zu geben und die seltsam aussehenden rekursiven Aufrufe loszuwerden, die dort stattfindenKeine dieser Lösungen funktionierte für meinen Anwendungsfall. Ich habe einige Formularfelder, die ng-change verwenden, um auf Änderungen zu achten. Die Verwendung
$watch
ist keine Hilfe, da sie nicht durch das automatische Ausfüllen ausgelöst wird. Da ich keine Schaltfläche zum Senden habe, gibt es keine einfache Möglichkeit, einige der Lösungen auszuführen, und ich habe Intervalle nicht erfolgreich verwendet.Am Ende habe ich das automatische Ausfüllen deaktiviert - nicht ideal, aber für den Benutzer viel weniger verwirrend.
Können Sie die Antwort hier
quelle
Wenn Sie jQuery verwenden, können Sie dies beim Senden des Formulars tun:
HTML:
JS:
quelle
Wenn Sie es einfach halten möchten, erhalten Sie den Wert einfach mit Javascript
In Ihrem Winkel-js-Controller:
var username = document.getElementById ('Benutzername'). value;
quelle