Angular'da Formlar
Kullanıcı girdisini formlarla yönetmek, birçok yaygın uygulamanın temel taşıdır.
Uygulamalar, kullanıcıların oturum açmasını, profil güncellemesini, hassas bilgi girmesini ve diğer birçok veri giriş görevini gerçekleştirmesini sağlamak için formları kullanır.
Angular, formlar aracılığıyla kullanıcı girdisini yönetmek için iki farklı yaklaşım sunar: reaktif ve şablon odaklı.
Her iki yaklaşım da kullanıcı girdi olaylarını görünümden yakalar, girdiyi doğrular, bir form ve veri modeli oluşturur ve değişiklikleri takip etmek için bir yol sağlar.
TIP: Yeni Signal Forms'u arıyorsanız, temel Signal Forms kılavuzumuza göz atın!
Bu kılavuz, durumunuz için en uygun form türünü belirlemenize yardımcı olacak bilgiler sağlar. Her iki yaklaşımın da kullandığı ortak yapı taşlarını tanıtır. Ayrıca iki yaklaşım arasındaki temel farkları özetler ve bu farkları kurulum, veri akışı ve test bağlamında gösterir.
Bir yaklaşım seçme
Reaktif formlar ve şablon odaklı formlar, form verilerini farklı şekilde işler ve yönetir. Her yaklaşım farklı avantajlar sunar.
| Formlar | Ayrıntılar |
|---|---|
| Reaktif formlar | Altta yatan form nesne modeline doğrudan, açık erişim sağlar. Şablon odaklı formlarla karşılaştırıldığında daha güçlüdürler: daha ölçeklenebilir, yeniden kullanılabilir ve test edilebilirdirler. Formlar uygulamanızın önemli bir parçasıysa veya uygulamanızı oluşturmak için zaten reaktif kalıplar kullanıyorsanız, reaktif formları kullanın. |
| Şablon odaklı formlar | Altta yatan nesne modelini oluşturmak ve yönetmek için şablondaki direktiflere dayanır. Bir uygulamaya basit bir form eklemek için kullanışlıdırlar; örneğin bir e-posta listesi kayıt formu. Uygulamaya eklemek kolaydır, ancak reaktif formlar kadar iyi ölçeklenmezler. Çok temel form gereksinimleriniz varsa ve mantık yalnızca şablonda yönetilebiliyorsa, şablon odaklı formlar uygun bir seçim olabilir. |
Temel farklar
Aşağıdaki tablo, reaktif ve şablon odaklı formlar arasındaki temel farkları özetlemektedir.
| Reaktif | Şablon odaklı | |
|---|---|---|
| Form modelinin kurulumu | Açık, bileşen sınıfında oluşturulur | Örtük, direktiflerle oluşturulur |
| Veri modeli | Yapılandırılmış ve değişmez | Yapılandırılmamış ve değiştirilebilir |
| Veri akışı | Senkron | Asenkron |
| Form doğrulama | Fonksiyonlar | Direktifler |
Ölçeklenebilirlik
Formlar uygulamanızın merkezi bir parçasıysa, ölçeklenebilirlik çok önemlidir. Form modellerini bileşenler arasında yeniden kullanabilmek kritiktir.
Reaktif formlar, şablon odaklı formlardan daha ölçeklenebilirdir. Altta yatan form API'sine doğrudan erişim sağlarlar ve görünüm ile veri modeli arasında senkron veri akışı kullanırlar, bu da büyük ölçekli formlar oluşturmayı kolaylaştırır. Reaktif formlar test için daha az kurulum gerektirir ve form güncellemelerini ve doğrulamayı düzgün bir şekilde test etmek için değişiklik algılamanın derinlemesine anlaşılmasını gerektirmez.
Şablon odaklı formlar basit senaryolara odaklanır ve yeniden kullanılabilirlik açısından sınırlıdır. Altta yatan form API'sini soyutlarlar ve görünüm ile veri modeli arasında asenkron veri akışı kullanırlar. Şablon odaklı formların soyutlaması test etmeyi de etkiler. Testler düzgün çalışması için manuel değişiklik algılama yürütmesine derinden bağımlıdır ve daha fazla kurulum gerektirir.
Form modelini kurma
Hem reaktif hem de şablon odaklı formlar, kullanıcıların etkileşimde bulunduğu form girdi öğeleri ile bileşen modelinizdeki form verileri arasındaki değer değişikliklerini takip eder. İki yaklaşım aynı temel yapı taşlarını paylaşır, ancak ortak form kontrolü örneklerini nasıl oluşturduğunuz ve yönettiğiniz konusunda farklılık gösterir.
Ortak form temel sınıfları
Hem reaktif hem de şablon odaklı formlar aşağıdaki temel sınıflar üzerine inşa edilmiştir.
| Temel sınıflar | Ayrıntılar |
|---|---|
FormControl |
Tek bir form kontrolünün değerini ve doğrulama durumunu takip eder. |
FormGroup |
Bir form kontrolleri koleksiyonu için aynı değerleri ve durumu takip eder. |
FormArray |
Bir form kontrolleri dizisi için aynı değerleri ve durumu takip eder. |
ControlValueAccessor |
Angular FormControl örnekleri ile yerleşik DOM öğeleri arasında bir köprü oluşturur. |
Reactive form'larda kurulum
Reaktif formlarda, form modelini doğrudan bileşen sınıfında tanımlarsınız.
[formControl] direktifi, açıkça oluşturulan FormControl örneğini, dahili bir değer erişimcisi kullanarak görünümdeki belirli bir form öğesine bağlar.
Aşağıdaki bileşen, reaktif formlar kullanarak tek bir kontrol için bir girdi alanı uygular.
Bu örnekte, form modeli FormControl örneğidir.
import {Component} from '@angular/core';
import {FormControl, ReactiveFormsModule} from '@angular/forms';
@Component({
selector: 'app-reactive-favorite-color',
template: ` Favorite Color: <input type="text" [formControl]="favoriteColorControl" /> `,
imports: [ReactiveFormsModule],
})
export class FavoriteColorReactive {
favoriteColorControl = new FormControl('');
}
IMPORTANT: Reaktif formlarda, form modeli doğruluk kaynağıdır; <input> öğesindeki [formControl] direktifi aracılığıyla, herhangi bir zamanda form öğesinin değerini ve durumunu sağlar.
Template-driven form'larda kurulum
Şablon odaklı formlarda, form modeli açık değil, örtüktür.
NgModel direktifi, belirli bir form öğesi için bir FormControl örneği oluşturur ve yönetir.
Aşağıdaki bileşen, şablon odaklı formlar kullanarak tek bir kontrol için aynı girdi alanını uygular.
import {Component, signal} from '@angular/core';
import {FormsModule} from '@angular/forms';
@Component({
selector: 'app-template-favorite-color',
template: ` Favorite Color: <input type="text" [(ngModel)]="favoriteColor" /> `,
imports: [FormsModule],
})
export class FavoriteColorTemplate {
favoriteColor = signal('');
}
IMPORTANT: Şablon odaklı bir formda doğruluk kaynağı şablondur. NgModel direktifi FormControl örneğini sizin için otomatik olarak yönetir.
Form'larda veri akışı
Bir uygulama form içerdiğinde, Angular'ın görünümü bileşen modeliyle ve bileşen modelini görünümle senkronize tutması gerekir. Kullanıcılar görünüm aracılığıyla değerleri değiştirdikçe ve seçimler yaptıkça, yeni değerler veri modelinde yansıtılmalıdır. Benzer şekilde, program mantığı veri modelindeki değerleri değiştirdiğinde, bu değerler görünümde yansıtılmalıdır.
Reaktif ve şablon odaklı formlar, kullanıcıdan veya programatik değişikliklerden gelen verilerin akışını farklı şekilde yönetir. Aşağıdaki diyagramlar, yukarıda tanımlanan favori renk girdi alanını kullanarak her form türü için her iki veri akışını da göstermektedir.
Reactive form'larda veri akışı
Reaktif formlarda, görünümdeki her form öğesi doğrudan form modeline (bir FormControl örneği) bağlıdır.
Görünümden modele ve modelden görünüme güncellemeler senkrondur ve kullanıcı arayüzünün nasıl oluşturulduğuna bağlı değildir.
Görünümden modele diyagramı, bir girdi alanının değeri görünümden değiştirildiğinde verilerin nasıl aktığını aşağıdaki adımlarla gösterir:
- Kullanıcı girdi öğesine bir değer yazar, bu durumda favori renk Blue.
- Form girdi öğesi en son değerle bir "input" olayı yayar.
- Form girdi öğesindeki olayları dinleyen
ControlValueAccessor, yeni değeri hemenFormControlörneğine aktarır. FormControlörneği,valueChangesobservable'ı aracılığıyla yeni değeri yayar.valueChangesobservable'ının tüm aboneleri yeni değeri alır.
Modelden görünüme diyagramı, modeldeki programatik bir değişikliğin görünüme nasıl yayıldığını aşağıdaki adımlarla gösterir.
- Kullanıcı
favoriteColorControl.setValue()yöntemini çağırır, bu daFormControldeğerini günceller. FormControlörneği,valueChangesobservable'ı aracılığıyla yeni değeri yayar.valueChangesobservable'ının tüm aboneleri yeni değeri alır.- Form girdi öğesindeki kontrol değeri erişimcisi, öğeyi yeni değerle günceller.
Template-driven form'larda veri akışı
Şablon odaklı formlarda, her form öğesi form modelini dahili olarak yöneten bir direktife bağlıdır.
Görünümden modele diyagramı, bir girdi alanının değeri görünümden değiştirildiğinde verilerin nasıl aktığını aşağıdaki adımlarla gösterir.
- Kullanıcı girdi öğesine Blue yazar.
- Girdi öğesi, Blue değeriyle bir "input" olayı yayar.
- Girdiye bağlı kontrol değeri erişimcisi,
FormControlörneğindekisetValue()yöntemini tetikler. FormControlörneği,valueChangesobservable'ı aracılığıyla yeni değeri yayar.valueChangesobservable'ının tüm aboneleri yeni değeri alır.- Kontrol değeri erişimcisi ayrıca
NgModel.viewToModelUpdate()yöntemini çağırır ve bu birngModelChangeolayı yayar. - Bileşen şablonu
favoriteColorözelliği için çift yönlü veri bağlama kullandığından, bileşendekifavoriteColorözelliğingModelChangeolayı tarafından yayılan değere (Blue) güncellenir.
Modelden görünüme diyagramı, favoriteColor Blue'dan Red'e değiştiğinde verilerin modelden görünüme nasıl aktığını aşağıdaki adımlarla gösterir
favoriteColordeğeri bileşende güncellenir.- Değişiklik algılama başlar.
- Değişiklik algılama sırasında, girdilerinden birinin değeri değiştiği için
NgModeldirektif örneğindengOnChangesyaşam döngüsü kancası çağrılır. ngOnChanges()yöntemi, dahiliFormControlörneği için değeri ayarlamak üzere asenkron bir görev kuyruğa alır.- Değişiklik algılama tamamlanır.
- Bir sonraki döngüde,
FormControlörneği değerini ayarlama görevi yürütülür. FormControlörneği,valueChangesobservable'ı aracılığıyla en son değeri yayar.valueChangesobservable'ının tüm aboneleri yeni değeri alır.- Kontrol değeri erişimcisi, görünümdeki form girdi öğesini en son
favoriteColordeğeriyle günceller.
NOTE: NgModel, değer değişikliği bir girdi bağlamadan kaynaklandığı için ExpressionChangedAfterItHasBeenChecked hatalarını önlemek amacıyla ikinci bir değişiklik algılama tetikler.
Veri modelinin değiştirilebilirliği
Değişiklik takip yöntemi, uygulamanızın verimliliğinde bir rol oynar.
| Formlar | Ayrıntılar |
|---|---|
| Reaktif formlar | Veri modelini değişmez bir veri yapısı olarak sağlayarak saf tutar. Veri modelinde her değişiklik tetiklendiğinde, FormControl örneği mevcut veri modelini güncellemek yerine yeni bir veri modeli döndürür. Bu size kontrolün observable'ı aracılığıyla veri modelindeki benzersiz değişiklikleri takip etme yeteneği verir. Değişiklik algılama daha verimlidir çünkü yalnızca benzersiz değişikliklerde güncelleme yapması gerekir. Veri güncellemeleri reaktif kalıpları takip ettiğinden, verileri dönüştürmek için observable operatörleriyle entegre edebilirsiniz. |
| Şablon odaklı formlar | Şablonda yapılan değişiklikler sırasında bileşendeki veri modelini güncellemek için çift yönlü veri bağlama ile değiştirilebilirliğe dayanır. Çift yönlü veri bağlama kullanılırken veri modelinde takip edilecek benzersiz değişiklikler olmadığından, değişiklik algılama güncellemelerin ne zaman gerekli olduğunu belirlemede daha az verimlidir. |
Fark, favori renk girdi öğesini kullanan önceki örneklerde gösterilmektedir.
- Reaktif formlarda,
FormControlörneği kontrolün değeri güncellendiğinde her zaman yeni bir değer döndürür - Şablon odaklı formlarda, favori renk özelliği her zaman yeni değerine göre değiştirilir
Form doğrulama
Doğrulama, herhangi bir form kümesini yönetmenin ayrılmaz bir parçasıdır. İster zorunlu alanları kontrol ediyor olun, ister mevcut bir kullanıcı adı için harici bir API'yi sorgulayın, Angular bir dizi yerleşik doğrulayıcının yanı sıra özel doğrulayıcılar oluşturma yeteneği sağlar.
| Formlar | Ayrıntılar |
|---|---|
| Reaktif formlar | Özel doğrulayıcıları, doğrulanacak bir kontrol alan fonksiyonlar olarak tanımlayın |
| Şablon odaklı formlar | Şablon direktiflerine bağlıdır ve doğrulama fonksiyonlarını saran özel doğrulayıcı direktifleri sağlamalıdır |
Daha fazla bilgi için Form Doğrulama bölümüne bakın.
Test etme
Test, karmaşık uygulamalarda büyük bir rol oynar. Formlarınızın doğru çalıştığını doğrularken daha basit bir test stratejisi yararlıdır. Reaktif formlar ve şablon odaklı formlar, form kontrolü ve form alanı değişikliklerine dayalı doğrulamalar yapmak için kullanıcı arayüzünün oluşturulmasına farklı düzeylerde bağımlıdır. Aşağıdaki örnekler, reaktif ve şablon odaklı formlarla formları test etme sürecini göstermektedir.
Reactive form'ları test etme
Reaktif formlar, senkron erişim sağladıkları ve kullanıcı arayüzünü oluşturmadan test edilebildikleri için nispeten basit bir test stratejisi sunar. Bu testlerde, durum ve veriler değişiklik algılama döngüsüyle etkileşime girmeden kontrol üzerinden sorgulanır ve işlenir.
Aşağıdaki testler, reaktif bir form için görünümden modele ve modelden görünüme veri akışlarını doğrulamak amacıyla önceki örneklerdeki favori renk bileşenlerini kullanır.
Görünümden modele veri akışını doğrulama
İlk örnek, görünümden modele veri akışını doğrulamak için aşağıdaki adımları gerçekleştirir.
- Form girdi öğesi için görünümü sorgulayın ve test için özel bir "input" olayı oluşturun.
- Girdi için yeni değeri Red olarak ayarlayın ve form girdi öğesinde "input" olayını gönderin.
- Bileşenin
favoriteColorControldeğerinin girdiden gelen değerle eşleştiğini doğrulayın.
Favorite color test - view to model
it('should update the value of the input field', () => {
const input = fixture.nativeElement.querySelector('input');
const event = createNewEvent('input');
input.value = 'Red';
input.dispatchEvent(event);
expect(fixture.componentInstance.favoriteColorControl.value).toEqual('Red');
});
Sonraki örnek, modelden görünüme veri akışını doğrulamak için aşağıdaki adımları gerçekleştirir.
- Yeni değeri ayarlamak için
FormControlörneği olanfavoriteColorControl'ü kullanın. - Form girdi öğesi için görünümü sorgulayın.
- Kontrolde ayarlanan yeni değerin girdideki değerle eşleştiğini doğrulayın.
Favorite color test - model to view
it('should update the value in the control', () => {
component.favoriteColorControl.setValue('Blue');
const input = fixture.nativeElement.querySelector('input');
expect(input.value).toBe('Blue');
});
Template-driven form'ları test etme
Şablon odaklı formlarla test yazmak, değişiklik algılama sürecinin ayrıntılı bilgisini ve direktiflerin her döngüde nasıl çalıştığının anlaşılmasını gerektirir; böylece öğeler doğru zamanda sorgulanabilir, test edilebilir veya değiştirilebilir.
Aşağıdaki testler, şablon odaklı bir form için görünümden modele ve modelden görünüme veri akışlarını doğrulamak amacıyla daha önce bahsedilen favori renk bileşenlerini kullanır.
Aşağıdaki test, görünümden modele veri akışını doğrular.
Favorite color test - view to model
it('should update the favorite color in the component', async () => {
const input = fixture.nativeElement.querySelector('input');
const event = createNewEvent('input');
input.value = 'Red';
input.dispatchEvent(event);
await fixture.whenStable();
expect(component.favoriteColor()).toEqual('Red');
});
Görünümden modele testinde gerçekleştirilen adımlar şunlardır.
- Form girdi öğesi için görünümü sorgulayın ve test için özel bir "input" olayı oluşturun.
- Girdi için yeni değeri Red olarak ayarlayın ve form girdi öğesinde "input" olayını gönderin.
- Test fikstürü aracılığıyla değişiklik algılamayı çalıştırın.
- Bileşenin
favoriteColorözellik değerinin girdiden gelen değerle eşleştiğini doğrulayın.
Aşağıdaki test, modelden görünüme veri akışını doğrular.
Favorite color test - model to view
it('should update the favorite color on the input field', async () => {
component.favoriteColor.set('Blue');
await fixture.whenStable();
const input = fixture.nativeElement.querySelector('input');
expect(input.value).toBe('Blue');
});
Modelden görünüme testinde gerçekleştirilen adımlar şunlardır.
favoriteColorözelliğinin değerini ayarlamak için bileşen örneğini kullanın.- Test fikstürü aracılığıyla değişiklik algılamayı çalıştırın.
- Sonraki oluşturmayı beklemek için
await fixture.whenStable()kullanın. - Form girdi öğesi için görünümü sorgulayın.
- Girdi değerinin bileşen örneğindeki
favoriteColorözelliğinin değeriyle eşleştiğini doğrulayın.
Sonraki adımlar
Reaktif formlar hakkında daha fazla bilgi edinmek için aşağıdaki kılavuzlara bakın:
Şablon odaklı formlar hakkında daha fazla bilgi edinmek için aşağıdaki kılavuzlara bakın: