Wysyłając formularz w AngularJS i korzystając z przeglądarki zapamiętaj hasło, a przy kolejnej próbie logowania pozwolisz przeglądarce wypełnić formularz logowania nazwą użytkownika i hasłem, $scope
model nie zostanie zmieniony na podstawie autouzupełniania.
Jedyny brudny hack, jaki znalazłem, to użycie następującej dyrektywy:
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);
}
};
}]);
Problem w tym, że ngModel.$setViewValue(element.val());
nie zmienia modelu ani widoku na podstawie element.val()
zwróconej wartości. Jak mogę to osiągnąć?
javascript
mvvm
angularjs
lucassp
źródło
źródło
Odpowiedzi:
Najwyraźniej jest to znany problem z Angular i obecnie jest otwarty
Nie jestem pewien, co mógłbyś tutaj zrobić oprócz jakiejś pracy, takiej jak próba. Wygląda na to, że jesteś na dobrej drodze. Nie udało mi się zmusić przeglądarki, aby spróbowała zapamiętać hasło do Twojego pliku plunk, więc nie jestem pewien, czy to zadziała, ale spójrz:
Myślę, że po prostu musisz trochę uprościć swoje podejście. Jedyną rzeczą, którą zdecydowanie zalecam, jest sprawdzenie
ngModel.$pristine
i upewnienie się, że nie nadpisujesz danych wejściowych złego użytkownika. Ponadto 3 sekundy to prawdopodobnie za długo. Nie powinieneś być zmuszony do wywoływania $ apply () w $ timeout, BTW, powinno automatycznie ustawić w kolejce $ podsumowanie.Prawdziwy haczyk: czy Twoja przeglądarka pokonuje Angulara w wykonaniu? A co z moją przeglądarką?
Jest to prawdopodobnie wojna nie do wygrania, dlatego Angular (lub Knockout) nie był w stanie jej łatwo rozwiązać. Nie ma gwarancji stanu danych wprowadzonych w momencie początkowego wykonania dyrektywy. Nawet w momencie inicjalizacji Angulara ... Więc jest to trudny problem do rozwiązania.
źródło
Oto rozwiązanie, które jest znacznie mniej hakerskie niż inne prezentowane rozwiązania i jest semantycznie poprawne AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/
Następnie wystarczy dołączyć dyrektywę do formularza:
źródło
Nie musisz używać
$timeout
ani niczego takiego. Możesz skorzystać z systemu zdarzeń.Myślę, że jest bardziej Angularish i nie zależy od jQuery ani niestandardowego przechwytywania zdarzeń.
Na przykład w programie obsługi przesyłania:
Następnie możesz mieć taką
autofill
dyrektywę:Wreszcie Twój kod HTML będzie wyglądał następująco:
źródło
Nie musisz już hakować! Angular dev tbosch stworzył polyfill, który wyzwala zdarzenie change, gdy przeglądarka zmienia pola formularza bez wyzwalania zdarzenia change:
https://github.com/tbosch/autofill-event
Na razie nie wbudują tego w kod Angular, ponieważ jest to poprawka błędu przeglądarki, a także działa bez Angulara (np. Dla zwykłych aplikacji jQuery).
„Wypełnienie będzie sprawdzać zmiany w ładowaniu dokumentu, a także po pozostawieniu danych wejściowych (tylko w tej samej formie). Jeśli chcesz, możesz jednak uruchomić sprawdzanie ręcznie.
Projekt zawiera testy jednostkowe, a także testy półautomatyczne, więc w końcu mamy miejsce na zebranie wszystkich różnych przypadków użycia wraz z wymaganymi ustawieniami przeglądarki.
Uwaga: to wypełnienie działa ze zwykłymi aplikacjami AngularJS, z aplikacjami AngularJS / jQuery, ale także ze zwykłymi aplikacjami jQuery, które nie używają Angular. "
Można go zainstalować z:
Dodaj skrypt
autofill-event.js
po jQuery lub Angular na swojej stronie.Spowoduje to wykonanie następujących czynności:
API (aby ręcznie uruchomić sprawdzanie):
$el.checkAndTriggerAutoFillEvent()
: Wykonaj sprawdzenie wszystkich elementów DOM w danym elemencie jQuery / jQLite.Jak to działa
Zapamiętaj wszystkie zmiany w elementach wejściowych przez użytkownika (nasłuchiwanie zdarzeń zmian), a także przez JavaScript (przechwytując $ el.val () dla elementów jQuery / jQLite). Ta zmieniona wartość jest przechowywana w elemencie we właściwości prywatnej.
Sprawdzanie elementu pod kątem automatycznego wypełnienia: Porównaj bieżącą wartość elementu z zapamiętaną wartością. Jeśli jest inny, wywołaj zdarzenie zmiany.
Zależności
AngularJS lub jQuery (działa z jednym lub dwoma)
Więcej informacji i źródło na stronie github .
Oryginalne wydanie Angular nr 1460 na Github można przeczytać tutaj.
źródło
ngModelOptions
w połączeniu zautofill-event
oznacza, że możesz teraz określićchange
jako jedno zeupdateOn
zdarzeń, aby upewnić się, że model jest poprawnie zsynchronizowany.Brudny kod, sprawdź, czy problem https://github.com/angular/angular.js/issues/1460#issuecomment-18572604 został naprawiony przed użyciem tego kodu. Ta dyrektywa wyzwala zdarzenia, gdy pole jest wypełnione, nie tylko przed przesłaniem (jest to konieczne, jeśli musisz obsłużyć dane wejściowe przed przesłaniem)
źródło
Wydaje się, że jasne rozwiązanie na wprost. Nie potrzeba jQuery.
AKTUALIZACJA:
źródło
$pristine
przed zmianą, a dopiero po zmianie zachować jego$pristine
stan. W przeciwnym razie okaże się, że jeśli formularz zostanie załadowany bez danych autouzupełniania, powyższa dyrektywa nadal będzie aktualizować model, a następnie sprawi, żedirty
nawet jeśli formant formularza powinien być nadal uważany za nietknięty. przykład tutaj, używając twojej dyrektywy. Skomentowałem kod, który chciałbym do niego dodać: jsfiddle.net/OACDesigns/L8Sja/4scope:true
powinno byćscope:{}
Rozwiązanie 1 [użycie $ timeout]:
Dyrektywa:
HTML:
Rozwiązanie 2 [Korzystanie ze zdarzeń kątowych]:
Ref: odpowiedź Becko
Dyrektywa:
HTML:
Rozwiązanie 3 [Korzystanie z wywołań metod przekazywania]:
Dyrektywa:
HTML:
źródło
model.$valid
dyrektywy zwraca wartość true zarówno przed, jak i po$setViewValue
, ale element nadal jest zng-invalid
klasąCóż, najłatwiej jest naśladować zachowanie przeglądarki, więc jeśli wystąpi problem ze zdarzeniem zmiany, po prostu uruchom je samodzielnie. Dużo prostsze.
Dyrektywa:
HTML:
Możesz zrobić kilka odmian, takich jak umieszczenie dyrektywy w formularzu i wywołanie zdarzenia na wszystkich wejściach z klasą .dirty podczas przesyłania formularza.
źródło
To jest sposób jQuery:
To jest Angular sposób:
HTML
źródło
triggerHandler('input')
powinno być ok, jeśli nie masz pełnego jqueryOto inne obejście, które jest mniej hakerskie, ale wymaga dodatkowego kodu w kontrolerze.
HTML:
Dyrektywa (CoffeeScript):
Kontroler:
źródło
To jedyne rozwiązanie, które znalazłem, które pozwoliło wszystkim walidacjom mojego Angulara działać zgodnie z przeznaczeniem, w tym wyłączyć / włączyć przycisk przesyłania. Instaluje się z altanką i 1 tagiem skryptu. Bazinga!
https://github.com/tbosch/autofill-event
źródło
Zmiana wartości modelu zamiast korzystania z funkcji limitu czasu zadziałała dla mnie.
Oto mój kod:
źródło
Jednowierszowe obejście w procedurze obsługi przesyłania (wymaga jQuery):
źródło
Wymuszam $ setValue (val ()) przy przesyłaniu: (to działa bez jQuery)
źródło
Jestem bardzo nowy w Angularjs, ale znalazłem proste rozwiązanie tego problemu => Zmuszanie Angulara do ponownej oceny wyrażenia ... zmieniając je! (oczywiście musisz zapamiętać wartość początkową, aby powrócić do stanu początkowego) Oto sposób, w jaki wygląda to w funkcji kontrolera podczas wysyłania formularza:
gdzie oczywiście wartość wprowadzona do hasła została ustawiona przez system Windows, a nie przez użytkownika.
źródło
Możesz wypróbować ten kod:
źródło
Niewielka modyfikacja tej odpowiedzi ( https://stackoverflow.com/a/14966711/3443828 ): użyj interwału $ zamiast limitu czasu $, aby nie musieć ścigać się z przeglądarką.
źródło
To jest rozwiązanie, które ostatecznie wykorzystałem w moich formularzach.
A szablon formularza będzie
W ten sposób mogłem uruchomić wszystkie parsery / elementy formatujące, które mam w moim modelu ng i mieć przejrzystą funkcjonalność przesyłania.
źródło
Rozwiązanie bez dyrektyw:
źródło
To prosta poprawka, która działa we wszystkich przypadkach, które przetestowałem zarówno w przeglądarce Firefox, jak i Chrome. Zauważ, że przy najwyższej odpowiedzi (dyrektywa bez limitu czasu) miałem problemy z -
Ta poprawka jest oczywiście bardzo głupia i hakerska, ale działa w 100% przypadków -
źródło
$timeout
z$interval
dać przyszłość DEVS nieco więcej kontekstu i pozbyć się dziwnie wyglądających wywołania rekurencyjne tam dziejeŻadne z tych rozwiązań nie działało w moim przypadku użycia. Mam kilka pól formularza, które używają ng-change do obserwowania zmian. Za pomocą
$watch
nie pomaga, ponieważ nie jest uruchamiane przez autouzupełnianie. Ponieważ nie mam przycisku przesyłania, nie ma łatwego sposobu na uruchomienie niektórych rozwiązań i nie udało mi się użyć interwałów.Skończyło się na wyłączeniu autouzupełniania - nie jest to idealne rozwiązanie, ale znacznie mniej zagmatwane dla użytkownika.
Znalazłem odpowiedź tutaj
źródło
Jeśli używasz jQuery, możesz to zrobić w formularzu:
HTML:
JS:
źródło
Jeśli chcesz zachować prostotę, po prostu uzyskaj wartość za pomocą javascript
W kontrolerze Angular JS:
var nazwa_użytkownika = document.getElementById ('nazwa_użytkownika'). wartość;
źródło