Saat mengirimkan formulir di AngularJS dan menggunakan fungsi ingat kata sandi browser, dan dalam upaya login berikutnya Anda membiarkan browser mengisi formulir login dengan nama pengguna dan kata sandi, $scope
model tidak akan diubah berdasarkan pengisian otomatis.
Satu-satunya peretasan kotor yang saya temukan adalah menggunakan petunjuk berikut:
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);
}
};
}]);
Masalahnya adalah bahwa ngModel.$setViewValue(element.val());
tidak mengubah model atau tampilan berdasarkan nilai yang element.val()
dikembalikan. Bagaimana saya bisa melakukannya?
javascript
mvvm
angularjs
lucassp
sumber
sumber
Jawaban:
Tampaknya ini adalah masalah yang diketahui dengan Angular dan saat ini terbuka
Saya tidak yakin apa yang dapat Anda lakukan di sini selain semacam pekerjaan yang Anda coba. Sepertinya Anda berada di jalur yang benar. Saya tidak bisa mendapatkan browser saya untuk mencoba mengingat kata sandi untuk plunk Anda, jadi saya tidak yakin apakah ini akan berhasil tetapi lihat:
Saya pikir Anda hanya perlu sedikit menyederhanakan pendekatan Anda. Satu hal yang saya rekomendasikan adalah memeriksa
ngModel.$pristine
dan memastikan Anda tidak menimpa beberapa masukan pengguna yang buruk. Juga, 3 detik mungkin terlalu lama. Anda tidak perlu memanggil $ apply () dalam $ timeout, BTW, itu akan mengantri $ digest untuk Anda secara otomatis.Tangkapan sebenarnya: Akankah browser Anda mengalahkan Angular hingga eksekusi? Bagaimana dengan browser saya?
Ini mungkin perang yang tidak dapat dimenangkan, itulah sebabnya Angular (atau Knockout) belum dapat menyelesaikannya dengan mudah. Tidak ada jaminan status data dalam masukan Anda pada saat eksekusi awal direktif. Bahkan tidak pada saat Angular inisialisasi .... Jadi ini masalah yang sulit dipecahkan.
sumber
Berikut adalah solusi yang jauh lebih sedikit hacky daripada solusi lain yang disajikan dan terdengar semantik AngularJS: http://victorblog.com/2014/01/12/fixing-autocomplete-autofill-on-angularjs-form-submit/
Kemudian Anda cukup melampirkan arahan ke formulir Anda:
sumber
Anda tidak harus menggunakan
$timeout
atau semacamnya seperti ini. Anda dapat menggunakan sistem acara.Saya pikir ini lebih Angularish dan tidak bergantung pada jQuery atau acara khusus.
Misalnya pada penangan kirim Anda:
Dan kemudian Anda dapat memiliki
autofill
arahan seperti ini:Terakhir, HTML Anda akan menjadi seperti ini:
sumber
Tidak perlu meretas lagi! Angular dev tbosch membuat polyfill yang memicu peristiwa perubahan saat browser mengubah kolom formulir tanpa memicu peristiwa perubahan:
https://github.com/tbosch/autofill-event
Untuk saat ini mereka tidak akan membangun ini menjadi kode Angular, karena ini adalah perbaikan bug untuk browser, dan juga bekerja tanpa Angular (misalnya untuk aplikasi jQuery biasa).
"Polyfill akan memeriksa perubahan pada pemuatan dokumen dan juga saat masukan tersisa (hanya dalam bentuk yang sama). Namun, Anda dapat memicu pemeriksaan secara manual jika Anda mau.
Proyek ini memiliki pengujian unit serta pengujian semi otomatis, jadi kami akhirnya memiliki tempat untuk mengumpulkan semua kasus penggunaan yang berbeda bersama dengan setelan browser yang diperlukan.
Harap diperhatikan: Polyfill ini bekerja dengan aplikasi AngularJS biasa, dengan aplikasi AngularJS / jQuery tetapi juga dengan aplikasi jQuery biasa yang tidak menggunakan Angular. "
Itu dapat diinstal dengan:
Tambahkan skrip
autofill-event.js
setelah jQuery atau Angular di halaman Anda.Ini akan melakukan hal berikut:
API (untuk memicu pemeriksaan secara manual):
$el.checkAndTriggerAutoFillEvent()
: Jalankan pemeriksaan untuk semua elemen DOM dalam elemen jQuery / jQLite yang diberikan.Bagaimana itu bekerja
Ingat semua perubahan pada elemen input oleh pengguna (mendengarkan peristiwa perubahan) dan juga oleh JavaScript (dengan mencegat $ el.val () untuk elemen jQuery / jQLite). Nilai yang diubah itu disimpan pada elemen di properti pribadi.
Memeriksa elemen untuk pengisian otomatis: Bandingkan nilai elemen saat ini dengan nilai yang diingat. Jika berbeda, picu peristiwa perubahan.
Dependensi
AngularJS atau jQuery (bekerja dengan salah satu atau keduanya)
Info dan sumber lebih lanjut di halaman github .
Original Angular Issue # 1460 di Github dapat dibaca disini.
sumber
ngModelOptions
digabungkan denganautofill-event
sarana sekarang Anda dapat menentukanchange
sebagai salah satuupdateOn
peristiwa untuk memastikan model Anda disinkronkan dengan benar.Kode kotor, periksa apakah masalah https://github.com/angular/angular.js/issues/1460#issuecomment-18572604 sudah diperbaiki sebelum menggunakan kode ini. Direktif ini memicu peristiwa ketika bidang diisi, tidak hanya sebelum pengiriman (ini diperlukan jika Anda harus menangani masukan sebelum mengirimkan)
sumber
Sepertinya solusi lurus ke depan yang jelas. Tidak perlu jQuery.
MEMPERBARUI:
sumber
$pristine
sebelum mengubahnya, dan kemudian setelah mengubahnya, pertahankan$pristine
statusnya. Jika tidak, Anda akan menemukan bahwa jika formulir dimuat tanpa data IsiOtomatis, perintah di atas akan tetap memperbarui model dan selanjutnya membuatnyadirty
meskipun kontrol formulir masih dianggap tidak tersentuh. contoh di sini, menggunakan direktif Anda. Saya telah mengomentari kode yang akan saya tambahkan: jsfiddle.net/OACDesigns/L8Sja/4scope:true
harusscope:{}
Solusi 1 [Menggunakan $ timeout]:
Pengarahan:
HTML:
Solusi 2 [Menggunakan kejadian bersudut]:
Ref: Jawaban Becko
Pengarahan:
HTML:
Solusi 3 [Menggunakan panggilan metode relai]:
Pengarahan:
HTML:
sumber
model.$valid
direktif mengembalikan nilai true baik sebelum dan sesudah$setViewValue
, tetapi elemen masih denganng-invalid
kelasNah, cara termudah itu untuk meniru perilaku browser, jadi jika ada masalah dengan event perubahan, aktifkan saja sendiri. Jauh lebih sederhana.
Pengarahan:
HTML:
Anda dapat melakukan beberapa variasi, seperti meletakkan direktif pada formulir dan mengaktifkan peristiwa pada semua input dengan kelas .dirty pada pengiriman formulir.
sumber
Ini adalah cara jQuery:
Ini adalah cara Angular:
HTML
sumber
triggerHandler('input')
seharusnya baik-baik saja jika Anda tidak memiliki jquery yang lengkapBerikut solusi lain yang tidak terlalu meretas, tetapi memerlukan beberapa kode tambahan di pengontrol.
HTML:
Petunjuk (CoffeeScript):
Pengontrol:
sumber
Ini adalah satu-satunya solusi yang saya temukan yang memungkinkan semua validasi Angular saya berfungsi seperti yang dirancang termasuk nonaktifkan / aktifkan tombol kirim. Instal dengan bower dan 1 tag skrip. Bazinga!
https://github.com/tbosch/autofill-event
sumber
Mengubah nilai model, daripada menggunakan fungsi batas waktu berhasil untuk saya.
Ini kode saya:
sumber
Solusi satu baris di penangan kirim (memerlukan jQuery):
sumber
Saya memaksa $ setValue (val ()) saat mengirimkan: (ini berfungsi tanpa jQuery)
sumber
Saya sangat baru mengenal Angularjs, tetapi saya menemukan solusi sederhana untuk masalah itu => Paksa Angular untuk mengevaluasi ulang ekspresi ... dengan mengubahnya! (tentu saja Anda perlu mengingat nilai awal untuk kembali ke keadaan awal) Berikut ini caranya dalam fungsi pengontrol Anda untuk mengirimkan formulir:
di mana tentu saja, nilai yang dimasukkan dalam input kata sandi Anda telah diatur oleh windows dan bukan oleh pengguna.
sumber
Anda dapat mencoba kode ini:
sumber
Modifikasi kecil untuk jawaban ini ( https://stackoverflow.com/a/14966711/3443828 ): gunakan $ interval alih-alih $ batas waktu sehingga Anda tidak perlu balapan browser.
sumber
Ini adalah solusi yang akhirnya saya gunakan dalam formulir saya.
Dan Templat formulirnya adalah
Dengan cara ini saya dapat menjalankan parser / pemformatan apa pun yang saya miliki di model-ng saya dan memiliki fungsionalitas kirim transparan.
sumber
Solusi tanpa arahan:
sumber
Ini adalah perbaikan sederhana yang berfungsi untuk semua kasus yang telah saya uji di Firefox dan Chrome. Perhatikan bahwa dengan jawaban teratas (direktif w / timeout) saya memiliki masalah dengan -
Perbaikan ini jelas sangat bodoh dan hacky, tetapi selalu berhasil 100% -
sumber
$timeout
dengan$interval
memberikan konteks yang lebih banyak kepada pengembang masa depan dan menyingkirkan panggilan rekursif yang tampak aneh yang terjadi di sanaTak satu pun dari solusi ini berfungsi untuk kasus penggunaan saya. Saya memiliki beberapa kolom formulir yang menggunakan ng-change untuk melihat perubahan. Menggunakan
$watch
tidak membantu karena tidak dipicu oleh IsiOtomatis. Karena saya tidak memiliki tombol kirim, tidak ada cara mudah untuk menjalankan beberapa solusi dan saya tidak berhasil menggunakan interval.Saya akhirnya menonaktifkan IsiOtomatis - tidak ideal tetapi jauh lebih tidak membingungkan pengguna.
Temukan jawabannya di sini
sumber
Jika Anda menggunakan jQuery, Anda dapat melakukan ini pada pengiriman formulir:
HTML:
JS:
sumber
Jika Anda ingin membuatnya tetap sederhana, dapatkan nilainya menggunakan javascript
Di pengontrol js sudut Anda:
var namapengguna = document.getElementById ('namapengguna'). nilai;
sumber