Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Angular

Pengenalan Form di Angular 4: Reactive Forms

by
Difficulty:BeginnerLength:LongLanguages:
This post is part of a series called Introduction to Forms in Angular 4.
Introduction to Forms in Angular 4: Template-Driven Forms
Introduction to Forms in Angular 4: Writing Custom Form Validators

Indonesian (Bahasa Indonesia) translation by Andy Nur (you can also view the original English article)

Final product image
What You'll Be Creating

Ini adalah bagian kedua dari seri Pengenalan Form di Angular 4. Pada bagian pertama, kita membuat form dengan menggunakan pendekatan template-driven. Kita menggunakan directive seperti ngModel, ngModelGroup dan ngForm untuk mengungguli elemen form. Dalam tutorial ini, kita akan mengambil pendekatan yang berbeda terhadap untuk membuat form—cara reaktif.

Reactive Forms

Rective forms mengambil pendekatan yang berbeda dibandingkan dengan bentuk template-driven. Di sini, kita membuat dan menginisialisasi objek kontrol form di class komponen kita. Mereka adalah objek perantara yang memegang state di form. Kita kemudian akan mengikat mereka ke elemen kontrol form dalam template.

Objek kontrol bentuk mendengarkan perubahan nilai kontrol masukan, dan segera tercermin dalam keadaan objek. Karena komponen memiliki akses langsung ke struktur model data, semua perubahan dapat disinkronkan antara model data, objek kontrol form, dan nilai kontrol inputan.

High level overview of Reactive forms using model-driven approach

Praktis berbicara, jika kita sedang membangun form untuk memperbarui profil pengguna, model data adalah objek pengguna yang diambil dari server. Dengan konvensi, ini sering disimpan di dalam properti pengguna komponen (this.user). Objek kontrol form atau model form akan terikat pada elemen kontrol form template yang sebenarnya.

Kedua model ini harus memiliki struktur yang serupa, meski keduanya tidak identik. Namun, nilai input tidak boleh mengalir ke model data secara langsung. Gambar tersebut menjelaskan bagaimana input pengguna dari template membuat jalan ke model form.

Mari kita mulai.

Prasyarat

Anda tidak perlu mengikuti bagian pertama dari seri ini, untuk bagian kedua agar masuk akal. Namun, jika kamu baru mengenal form di Angular, saya akan sangat merekomendasikannya melalui strategi template-driven. Kode untuk proyek ini tersedia di repositori GitHub saya. Pastikan kamu berada di branch yang benar dan kemudian unduh zip atau, sebagai alternatif, kloning repo untuk melihat form beraksi.

Jika kamu lebih memilih untuk memulai dari awal, pastikan kamu telah menginstal Angular CLI. Gunakan perintah ng untuk membuat proyek baru.

Selanjutnya, buat komponen baru untuk SignupForm atau buat secara manual.

Ganti isi app.component.html dengan ini:

Berikut adalah struktur direktori untuk direktori src/. Saya telah menghapus beberapa file yang tidak penting agar semuanya tetap sederhana.

Seperti yang dapat kamu lihat, sebuah direktori untuk komponen SignupForm telah dibuat secara otomatis. Di situlah sebagian besar kode kita akan tertuju. Saya juga telah membuat User.ts baru untuk menyimpan model User kita.

Template HTML

Sebelum kita menyelami template komponen yang sebenarnya, kita perlu memiliki gagasan abstrak tentang apa yang sedang kita buat. Jadi, inilah bentuk struktur yang ada dalam pikiran saya. Form pendaftaran akan memiliki beberapa field input, elemen select, dan elemen checkbox.

The HTML Template

Berikut adalah template HTML yang akan kita gunakan untuk halaman registrasi kita.

Template HTML

Kelas CSS yang digunakan dalam template HTML adalah bagian dari library Bootstrap yang digunakan untuk membuat semuanya cantik. Karena ini bukan tutorial desain, saya tidak akan banyak membicarakan aspek CSS dari form kecuali jika diperlukan.

Dasar Pengaturan Form

Untuk membuat Rective form, kamu perlu mengimpor ReactiveFormsModule dari @angular/forms dan tambahkan ini ke array imports di app.module.ts.

app/app.module.ts

Selanjutnya, buatlah model User untuk form pendaftaran. Kita bisa menggunakan class atau antarmuka untuk membuat model. Untuk tutorial ini, saya akan mengekspor class dengan properti berikut.

app/User.ts

Sekarang, buat sebuah instance dari model User di komponen SignupForm.

app/signup-form/signup-form.component.ts

Untuk file signup-form.component.html, saya akan menggunakan template HTML yang sama dibahas di atas, namun dengan sedikit perubahan. Formulir pendaftaran memiliki field select dengan daftar opsi. Meskipun itu berhasil, kita akan melakukannya dengan cara Angular dengan melakukan perulangan pada daftar menggunakan directive ngFor.

app/signup-form/signup-form.component.html

Catatan: Kamu mungkin mendapatkan pesan error yang mengatakan No provider for ControlContainer. Error muncul saat komponen memiliki tag tanpa directive formGroup. Error akan hilang begitu kita menambahkan directive formGroup nanti di tutorial.

Kita memiliki komponen, model, dan template form yang ada. Sekarang apa? Sudah waktunya untuk membuat tangan kita kotor dan berkenalan dengan API yang kamu butuhkan untuk membuat reactive forms. Ini termasuk FormControl dan FormGroup.

Melacak State Menggunakan FormControl

Sementara membangun form dengan strategi reactice forms, kamu tidak akan menemukan perintah ngModel dan ngForm. Sebagai gantinya, kita menggunakan API FormControl dan FormGroup yang mendasarinya.

FormControl adalah perintah yang digunakan untuk membuat instance FormControl yang dapat kamu gunakan untuk melacak state elemen form dan status validasinya. Beginilah cara kerja FormControl:

email sekarang adalah instance FormControl, dan kamu dapat mengikatnya ke elemen kontrol input di templatemu sebagai berikut:

Elemen form template sekarang terikat pada contoh FormControl di komponen. Apa artinya perubahan pada nilai kontrol inputan tercermin di ujung yang lain.

Konstruktor FormControl menerima tiga argumen—nilai awal, array validator sinkronisasi, dan serangkaian validator async—dan seperti yang kamu duga, semuanya opsional. Kita akan membahas dua argumen pertama di sini.

Angular memiliki seperangkat validator bawaan yang terbatas. Metode validator yang populer meliputi Validators.required, Validators.minLength, Validators.maxlength, dan Validators.pattern. Namun, untuk menggunakannya, Anda harus mengimpor API Validator terlebih dahulu.

Untuk form pendaftaran, kita memiliki beberapa field kontrol input (untuk email dan password), field select, dan field checkbox. Daripada membuat objek FormControl individual, bukankah lebih masuk akal untuk mengelompokkan semua FormControls ini di bawah satu entitas? Hal ini bermanfaat karena kita sekarang bisa melacak nilai dan kevalidan semua objek sub-FormControl di satu tempat. Itulah FormGroup. Jadi kita akan mendaftarkan FormGroup induk dengan beberapa anak FormControls.

Grup Beberapa FormControls Dengan FormGroup

Untuk menambahkan FormGroup, impor dulu. Selanjutnya, deklarasikan signupForm sebagai properti class dan inisialisasi sebagai berikut:

app/signup-form/signup-form.component.ts

Bind FormGroup model ke DOM sebagai berikut:

app/signup-form/signup-form.component.html

[formGroup] = "signupForm" memberitahu Angular bahwa kamu ingin mengaitkan formulir ini dengan FormGroup yang dideklarasikan di class komponen. Ketika Angular melihat formControlName = "email", ia akan memeriksa sebuah instance dari FormControl dengan nilai kunci email di dalam FormGroup induk.

Demikian pula, perbarui elemen bentuk lainnya dengan menambahkan atribut formControlName = "value" seperti yang baru saja kita lakukan di sini.

Untuk melihat apakah semuanya bekerja seperti yang diharapkan, tambahkan berikut ini setelah tag form:

app/signup-form/signup-form.component.html

Pipa properti SignupForm melalui JsonPipe untuk membuat model sebagai JSON di browser. Ini sangat membantu untuk debugging dan logging. Kamu seharusnya melihat output JSON seperti ini.

Form state and validty in Model-driven forms

Ada dua hal yang perlu dicatat disini:

  1. JSON tidak sama persis dengan struktur model user yang kita buat tadi.
  2. SignupForm.status menunjukkan bahwa status form adalah INVALID. Ini jelas menunjukkan bahwa Validators.required pada bidang field kontrol email yang bekerja seperti yang diharapkan.

Struktur model form dan model data harus sesuai.

Untuk mendapatkan struktur hierarkis model data, kita harus menggunakan FormGroup bersarang. Selain itu, selalu ada ide bagus untuk memiliki elemen form terkait di bawah satu FormGroup tunggal.

FormGroup Bersarang

Buat FormGroup baru untuk passwordnya.

app/signup-form/signup-form.component.ts

Sekarang, untuk mengikat model form baru dengan DOM, buat perubahan berikut:

app/signup-form/signup-form.component.html

formGroupName = "password" melakukan binding untuk FormGroup bersarang. Sekarang, struktur model form sesuai dengan kebutuhan kita.

Selanjutnya, kita perlu memvalidasi kontrol form.

Memvalidasi Form

Kita memiliki validasi sederhana untuk kontrol inputan email. Namun, itu tidak cukup. Berikut adalah daftar seluruh kebutuhan kita untuk validasinya.

  • Semua elemen kontrol form diwajibkan.
  • Nonaktifkan tombol submit sampai status form-nya VALID.
  • Field email harus berisi id email secara ketat.
  • Feld password harus memiliki panjang minimum 8.
Validating the form

Yang pertama itu mudah. Tambahkan Validator.required ke semua FormControls dalam model form.

app/signup-form/signup-form.component.ts

Selanjutnya, nonaktifkan tombol selagi form INVALID.

app/signup-form/signup-form.component.html

Untuk menambahkan pembatas pada email, kamu dapat menggunakan Validator.email bawaan atau membuat Validators.pattern() yang menunjukkan reguler expressions seperti yang ada di bawah ini:

Gunakan validator minLength untuk kolom password.

Itu untuk validasi. Namun, bentuk logika model tampak berantakan dan berulang-ulang. Mari rapikan itu terlebih dulu.

Refaktori Kode Menggunakan FormBuilder

Angulat memberimu sintaks yang manis untuk membuat instance baru dari FormGroup dan FormControl yang disebut FormBuilder. API FormBuilder tidak melakukan sesuatu yang istimewa selain yang telah kita bahas di sini.

Ini menyederhanakan kode kita dan membuat proses pembuatan form tampak terlihat mudah. Untuk membuat FormBuilder, kamu harus mengimpornya ke signup-form.component.ts dan menyuntikkan FormBuilder ke dalam konstruktor.

app/signup-form/signup-form.component.ts

Daripada membuat FormGroup() baru, kita dapat menggunakan this.fb.group untuk membuat form. Kecuali sintaksnya, semuanya tetap sama.

app/signup-form/signup-form.component.ts

Menampilkan Error Validasi

Untuk menampilkan error, saya akan menggunakan perintah kondisional ngIf pada elemen div. Mari kita mulai dengan field kontrol inputan untuk email:

Ada beberapa masalah di sini.

  1. Darimana asal invalid dan pristine?
  2. signupForm.controls.email.invalid terlalu panjang dan mendalam.
  3. Error tersebut tidak secara eksplisit mengatakan mengapa hal itu tidak valid.

Untuk menjawab pertanyaan pertama, setiap FormControl memiliki sifat tertentu seperti invalidvalidpristinedirtytouched, dan untouched. Kita bisa menggunakan ini untuk mengetahui apakah pesan error atau peringatan harus ditampilkan atau tidak. Gambar di bawah menggambarkan masing-masing sifat tersebut secara rinci.

 FormControl Properties in Angular Reactive approach

Jadi elemen div dengan *ngIf akan diberikan hanya jika email tidak valid. Namun, pengguna akan disambut dengan error tentang field inputan yang kosong bahkan sebelum mereka sempat mengubah form.

Untuk menghindari skenario ini, kita menambahkan kondisi kedua. Error akan ditampilkan hanya setelah kontrol telah dikunjungi.

Untuk menyingkirkan rantai panjang pada nama metode (signupForm.controls.email.invalid), saya akan menambahkan beberapa metode getter singkat. Hal ini membuatnya lebih mudah diakses dan singkat.

app/signup-form/signup-form.component.ts

Untuk membuat error lebih eksplisit, saya telah menambahkan kondisi ngIf bersarang di bawah ini:

app/signup-form/signup-form.component.html

Kita menggunakan email.errors untuk memeriksa semua kemungkinan error validasi dan kemudian menampilkannya kembali ke pengguna dalam bentuk pesan khusus. Sekarang, ikuti prosedur yang sama untuk elemen form lainnya. Berikut adalah cara saya membuat kode validasi untuk password dan persyaratan kontrol inputan.

app/signup-form/signup-form.component.html

Mengirim Form Menggunakan ngSubmit

Kita hampir selesai dengan form-nya. Ini tidak memiliki fungsi submit, akan kita implementasikan sekarang.

Pada form submit, nilai model form harus mengalir ke dalam properti komponen pengguna.

app/signup-form/signup-form.component.ts

Demo Akhir

Berikut adalah versi terakhir dari aplikasi. Saya telah menambahkan beberapa class Bootstrap untuk membuat form menjadi menarik.

Rangkuman

Jika kamu telah mengikuti rangkaian tutorial ini sejak awal, kita memiliki pengalaman langsung dengan dua teknologi pembuatan form populer di Angular. Teknik template-driven dan model-driven adalah dua cara untuk mencapai hal yang sama. Secara pribadi, saya lebih suka menggunakan formu reactive karena alasan berikut:

  • Semua logika validasi form akan ditempatkan di satu tempat—di dalam class komponenmu. Ini jauh lebih produktif daripada pendekatan template, dimana directive ngModel tersebar di seluruh template.
  • Tidak seperti form template-driven, form Model-driven lebih mudah untuk dites. Kamu tidak perlu menggunakan library tes end-to-end untuk menguji form-mu.
  • Validasi logika akan masuk ke dalam class komponen dan bukan di template.
  • Untuk form dengan sejumlah elemen form yang besar, pendekatan ini memiliki sesuatu yang disebut FormBuilder untuk membuat pembuatan objek FormControl menjadi lebih mudah.

Kita melewatkan satu hal, dan itu adalah penulisan validator untuk ketidakcocokan password. Di bagian akhir dari seri ini, kita akan membahas semua hal yang perlu kamu ketahui tentang membuat fungsi validator khusus di Angular. Nantikan terus sampai saat itu.

Sementara itu, ada banyak framework dan library yang membuatmu tetap sibuk, dengan banyak item di Envato Market untuk dibaca, dipelajari, dan digunakan.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.