Reactive Forms ile form yazmak: kurulumdan özel doğrulamaya adım adım
Angular Reactive Forms ile FormGroup, FormBuilder ve Validators kullanarak form kurma, hata mesajı gösterme ve özel doğrulayıcı yazma rehberi.
Reactive Forms ne zaman tercih edilir?
Angular, şablon tabanlı ve reaktif olmak üzere farklı form yaklaşımları sunar. Reactive Forms'ta form modeli bileşen sınıfında kodla tanımlanır, şablon yalnızca bu modele bağlanır. Doğrulama kuralları, değer değişimlerine tepki ve dinamik alan ekleme gibi işler kodda olduğu için test etmek ve yeniden kullanmak kolaydır. Çok adımlı, koşullu alanları olan ya da sunucuyla yoğun etkileşen kurumsal formlarda genelde bu yaklaşım seçilir.
Şablon tabanlı yaklaşım ise az alanlı, basit formlarda yeterli olabilir. Karar verirken şu soruyu sorun: doğrulama mantığını bileşenden bağımsız test etmem gerekecek mi ve alanlar çalışma sırasında değişecek mi? Evet ise Reactive Forms uygundur.
Kurulum: modül, FormGroup ve FormControl
Reaktif formu kullanmak için ReactiveFormsModule bileşenin imports listesine eklenir. Resmî belgeye göre temel yapı taşları şunlardır: FormControl tek bir girdinin değerini ve geçerliliğini, FormGroup adlandırılmış sabit bir denetim kümesini, FormArray ise sayısı değişebilen denetim listesini yönetir. FormBuilder ise bunları daha kısa yazmak için enjekte edilen bir yardımcıdır.
Örnek bir başvuru formu:
private fb = inject(FormBuilder);
basvuru = this.fb.group({ adSoyad: ['', Validators.required], eposta: ['', [Validators.required, Validators.email]], adres: this.fb.group({ sehir: [''], ilce: [''], }), });
Şablonda form elemanına [formGroup]="basvuru" ile, her girdiye formControlName="adSoyad" ile bağlanırsınız. İç içe grup için formGroupName kullanılır. Belgede de gösterildiği gibi, gerekli bir alan boşken üst formun geçerliliği de düşer; bu sayede gönder düğmesini formun genel durumuna bağlayabilirsiniz.
Doğrulama: yerleşik doğrulayıcılar ve hata mesajı
Doğrulayıcılar, bir denetimin değerini inceleyip geçerliyse boş, geçersizse bir hata nesnesi döndüren fonksiyonlardır. Angular, Validators sınıfı altında yaygın olanları verir: required, email, minLength, maxLength, pattern gibi. Birden çok doğrulayıcı dizi olarak verilir.
Gönder düğmesini formun durumuna bağlamak için: [disabled]="basvuru.invalid". Kullanıcıya hatayı göstermenin kuralı ise zamanlamadır: kullanıcı daha alana dokunmadan kırmızı hata göstermek rahatsız edicidir. Bu yüzden hata, alan dokunulmuş (touched) ya da kirlenmiş (dirty) olduktan sonra gösterilir:
@if (basvuru.controls.eposta.touched && basvuru.controls.eposta.hasError('required')) { E-posta zorunludur. }
Her doğrulayıcının kendi hata anahtarı vardır (required, email, minlength gibi); hasError ile bu anahtarı sorgulayıp uygun mesajı gösterirsiniz. Mesajları şablona dağıtmak yerine küçük bir yardımcı bileşende toplamak, büyük formlarda tekrarı önler.
Özel doğrulayıcı yazmak
Yerleşik doğrulayıcılar yetmediğinde kendi fonksiyonunuzu yazarsınız. Belgedeki örnek kalıp şudur: fonksiyon denetimi alır, geçerliyse null, geçersizse bir hata nesnesi döndürür.
Örnek: kurumsal e-posta alanı için alan adı kontrolü.
export function kurumsalEposta(izinli: string): ValidatorFn { return (denetim: AbstractControl) => { const deger = String(denetim.value ?? ''); return deger.endsWith(izinli) ? null : { kurumsalEposta: true }; }; }
Kullanımı: eposta: ['', [Validators.required, kurumsalEposta('@company.com')]]. Fonksiyonu bir fabrika olarak yazmak, parametre almasını sağlar ve aynı kuralı farklı alanlarda yeniden kullanmanızı mümkün kılar. Sunucuya sormak gerektiren doğrulamalar için (örneğin e-posta daha önce kayıtlı mı) asenkron doğrulayıcı kullanılır; bu tür kontrolleri her tuşta değil, alan terk edildiğinde ya da kısa bir bekleme sonrasında çalıştırmak, sunucuyu yormaz.
Alanlar arası doğrulama ve dinamik alanlar
Bazı kurallar tek alana değil, birkaç alana birden bağlıdır: şifre ile şifre tekrarının eşleşmesi, bitiş tarihinin başlangıçtan sonra olması gibi. Bu kurallar grubun doğrulayıcısı olarak yazılır: doğrulayıcı gruptaki denetimleri okur ve hata nesnesini gruba ekler. Hata alanı grupta olduğu için şablonda basvuru.hasError('sifreEslesmiyor') ile okunur.
Dinamik alanlar için FormArray kullanılır. Örneğin bir sipariş formunda kullanıcı istediği kadar kalem ekleyebiliyorsa, her kalem bir FormGroup'tur ve hepsi bir FormArray içinde tutulur. Ekle ve sil düğmeleri push ve removeAt metotlarını çağırır; şablonda @for ile döngü kurulur. Değer, tüm kalemleri içeren bir dizi olarak tek seferde alınabilir.
Koşullu alanlar için valueChanges ve statusChanges akışlarından yararlanılır: belgede bu akışlar, değer ve geçerlilik değişimlerine tepki vermek için tanıtılır. Örneğin "Fatura bilgisi gerekli mi" seçeneği değişince ilgili grubun doğrulayıcılarını ekleyip çıkarırsınız.
Gönderme akışı ve sık hatalar
Gönderme anında şu sırayı izleyin: formun geçerliliğini kontrol edin, geçersizse tüm denetimleri dokunulmuş olarak işaretleyin (markAllAsTouched) ki gizli kalan hatalar görünsün, geçerliyse getRawValue ya da value ile veriyi alıp servise iletin. Sunucudan gelen alan hatalarını da forma geri yazın (setErrors); böylece kullanıcı hatayı ilgili alanın yanında görür.
Sık yapılan hatalar:
- ReactiveFormsModule'ü imports'a eklememek; bu durumda formGroup bağlamı tanınmaz.
- formControlName ile modeldeki anahtar adlarının uyuşmaması.
- Hata mesajını alana dokunulmadan göstermek.
- Doğrulama mantığını şablona gömmek; kural değişince birçok yer güncellenir.
- Her değer değişiminde sunucuya istek atmak; bekleme ve iptal için RxJS operatörlerini kullanın.
Formları test ederken bileşeni render etmeye gerek kalmadan, sınıftaki form modelini doğrudan çalıştırıp geçerlilik sonuçlarını denetleyebilirsiniz. Bu, Reactive Forms'un en pratik kazanımlarından biridir.
Mindset programında yeri
Mindset'in Angular ile Kurumsal Web Uygulamaları programında "Formlar, Yönlendirme ve Yetkilendirme" modülü bu konuyu, kullanıcı girişi yoğun yönetim ekranları gibi kurumsal bağlamda ele alır. Bir başvuru, sipariş ya da kayıt ekranını sıfırdan geliştirecek arayüz geliştiricileri için; formun yönlendirme ve yetki kuralları ile birlikte düşünülmesi gereken ekipler için uygundur. Formun doğrulama kuralları çoğu zaman rol ve yetkiyle iç içe geçtiğinden, aynı modülde yönlendirme ve yetkilendirmenin birlikte çalışılması, formu ekranın geri kalanından kopuk değil, uygulamanın bütünü içinde tasarlamaya yardımcı olur. Bu, özellikle birden çok geliştiricinin aynı form altyapısını paylaştığı ekiplerde ortak bir standart oluşturmak için işe yarar.
İlgili Mindset programı
Angular ile Kurumsal Web Uygulamaları
Sık sorulan sorular
Template-driven form ile Reactive Forms arasında hangisini seçmeliyim?
Az alanlı, basit ve doğrulaması kısıtlı formlarda şablon tabanlı yaklaşım yeterli olabilir. Dinamik alanlar, özel doğrulama, test edilebilirlik ve karmaşık akışlar gerekiyorsa Reactive Forms daha uygundur. Bir projede ikisini karıştırmak yerine tek yaklaşımda standartlaşmak bakımı kolaylaştırır.
Hata mesajı neden ekranda görünmüyor?
Genellikle hata mesajı için koşul yanlış kuruludur ya da alan dokunulmuş olarak işaretlenmemiştir. Denetimin hasError ile ilgili hata anahtarını sorguladığınızı, touched ya da dirty koşulunu doğru yazdığınızı ve formControlName değerinin model anahtarıyla aynı olduğunu kontrol edin.
FormBuilder kullanmak zorunlu mu?
Hayır. FormGroup ve FormControl nesnelerini new ile elle de oluşturabilirsiniz. FormBuilder yalnızca aynı işi daha kısa yazmanızı sağlayan bir yardımcıdır. Uzun formlarda okunabilirlik kazandırdığı için çoğu proje onu tercih eder.
Form değerlerini dışarıdan nasıl doldururum?
Tüm alanları birden doldurmak için setValue, yalnızca bazılarını güncellemek için patchValue kullanılır. setValue modeldeki tüm anahtarları bekler, patchValue ise eksik anahtarlara izin verir. Sunucudan gelen veriyle formu doldururken genellikle patchValue daha esnektir.
Form geçerli olduğu halde gönder düğmesi neden pasif?
Büyük olasılıkla bir alt grup, FormArray ya da asenkron doğrulayıcı hâlâ geçersiz ya da bekleme durumundadır. Üst formun geçerliliği tüm alt denetimlerin geçerliliğine bağlıdır. Formun status değerini ve her denetimin ayrı hata nesnesini ekrana yazdırarak hangisinin engel olduğunu bulabilirsiniz.
İlgili rehberler
Kategori: Yazılım Geliştirme