Reaktif formlar, değerleri zamanla değişen form girdilerini yönetmek için model odaklı bir yaklaşım sunar. Bu kılavuz, temel bir form kontrolünü nasıl oluşturacağınızı ve güncelleyeceğinizi, bir grupta birden fazla kontrolü nasıl kullanacağınızı, form değerlerini nasıl doğrulayacağınızı ve çalışma zamanında kontroller ekleyip kaldırabileceğiniz dinamik formlar oluşturmayı gösterir.
Reactive form'lara genel bakış
Reaktif formlar, belirli bir zamanda formun durumunu yönetmek için açık ve değişmez bir yaklaşım kullanır. Form durumundaki her değişiklik yeni bir durum döndürür ve değişiklikler arasında modelin bütünlüğünü korur. Reaktif formlar, observable akışlar etrafında inşa edilmiştir; burada form girdileri ve değerleri, senkron olarak erişilebilen akışlar olarak sağlanır.
Reaktif formlar ayrıca test etmek için basit bir yol sağlar çünkü verilerinizin istendiğinde tutarlı ve öngörülebilir olduğundan emin olursunuz. Akışların tüm tüketicileri bu verilere güvenli bir şekilde erişebilir ve işleyebilir.
Reaktif formlar, şablon odaklı formlardan belirgin şekillerde farklıdır. Reaktif formlar, veri modeline senkron erişim, observable operatörleriyle değişmezlik ve observable akışlar aracılığıyla değişiklik takibi sağlar.
Şablon odaklı formlar, şablonunuzdaki verilere doğrudan erişim ve değiştirme izni verir, ancak reaktif formlardan daha az açıktır çünkü şablona gömülü direktiflere dayanırlar ve değişiklikleri asenkron olarak takip etmek için değiştirilebilir veriler kullanırlar. İki paradigma arasındaki ayrıntılı karşılaştırmalar için Formlara Genel Bakış bölümüne bakın.
Temel bir form kontrolü ekleme
Form kontrollerini kullanmanın üç adımı vardır.
- Yeni bir bileşen oluşturun ve reaktif formlar modülünü kaydedin. Bu modül, reaktif formları kullanmak için gereken reaktif form direktiflerini bildirir.
- Yeni bir
FormControlörneği oluşturun. FormControl'ü şablonda kaydedin.
Daha sonra bileşeni şablona ekleyerek formu görüntüleyebilirsiniz.
Aşağıdaki örnekler, tek bir form kontrolünün nasıl ekleneceğini gösterir. Örnekte, kullanıcı bir girdi alanına adını girer, bu girdi değeri yakalanır ve form kontrol öğesinin geçerli değeri görüntülenir.
-
Yeni bir bileşen oluşturun ve ReactiveFormsModule'ü içe aktarın
@angular/formspaketindenReactiveFormsModule'ü içe aktarıp Component'inizinimportsdizisine eklemek için CLI komutung generate componentkullanarak projenizde bir bileşen oluşturun.name-editor.component.ts (excerpt)
import {FormControl, ReactiveFormsModule} from '@angular/forms'; @Component({ selector: 'app-name-editor', templateUrl: './name-editor.component.html', styleUrls: ['./name-editor.component.css'], imports: [ReactiveFormsModule], }) export class NameEditorComponent { -
Bir FormControl örneği bildirin
Başlangıç değerini ayarlamak için
FormControlyapıcısını kullanın; bu örnekte boş bir dizedir. Bu kontrolleri bileşen sınıfınızda oluşturarak, form girdisinin durumunu dinlemek, güncellemek ve doğrulamak için anında erişim elde edersiniz.name-editor.component.ts
import {Component} from '@angular/core'; import {FormControl, ReactiveFormsModule} from '@angular/forms'; @Component({ selector: 'app-name-editor', templateUrl: './name-editor.component.html', styleUrls: ['./name-editor.component.css'], imports: [ReactiveFormsModule], }) export class NameEditorComponent { name = new FormControl(''); } -
Kontrolü şablonda kaydedin
Kontrolü bileşen sınıfında oluşturduktan sonra, onu şablondaki bir form kontrol öğesiyle ilişkilendirmeniz gerekir.
ReactiveFormsModule'de de bulunanFormControlDirectivetarafından sağlananformControlbağlamasını kullanarak şablonu form kontrolüyle güncelleyin.name-editor.component.html
<label for="name">Name: </label> <input id="name" type="text" [formControl]="name" />Şablon bağlama sözdizimini kullanarak, form kontrolü artık şablondaki
namegirdi öğesine kaydedilmiştir. Form kontrolü ve DOM öğesi birbirleriyle iletişim kurar: görünüm modeldeki değişiklikleri yansıtır ve model görünümdeki değişiklikleri yansıtır. -
Bileşeni görüntüleyin
nameözelliğine atananFormControl,<app-name-editor>bileşeni bir şablona eklendiğinde görüntülenir.app.component.html (name editor)
<app-name-editor />
Form kontrol değerini görüntüleme
Değeri aşağıdaki yollarla görüntüleyebilirsiniz:
valueChangesobservable'ı aracılığıyla; şablondaAsyncPipekullanarak veya bileşen sınıfındasubscribe()yöntemiyle formun değerindeki değişiklikleri dinleyebilirsiniz- Geçerli değerin anlık görüntüsünü veren
valueözelliğiyle
Aşağıdaki örnek, şablonda interpolasyon kullanarak geçerli değerin nasıl görüntüleneceğini gösterir.
name-editor.component.html (control value)
<p>Value: {{ name.value }}</p>
Görüntülenen değer, form kontrol öğesini güncellediğinizde değişir.
Reaktif formlar, her örnekle sağlanan özellikler ve yöntemler aracılığıyla belirli bir kontrol hakkında bilgiye erişim sağlar. Altta yatan AbstractControl sınıfının bu özellikleri ve yöntemleri, form durumunu kontrol etmek ve girdi doğrulamasını yönetirken mesajların ne zaman görüntüleneceğini belirlemek için kullanılır.
Diğer FormControl özellikleri ve yöntemleri hakkında API Referansı bölümünden bilgi alabilirsiniz.
Form kontrol değerini değiştirme
Reaktif formlar, bir kontrolün değerini programatik olarak değiştirmek için yöntemlere sahiptir ve bu size kullanıcı etkileşimi olmadan değeri güncelleme esnekliği sağlar.
Bir form kontrol örneği, form kontrolünün değerini güncelleyen ve sağlanan değerin yapısını kontrolün yapısına göre doğrulayan bir setValue() yöntemi sağlar.
Örneğin, bir arka uç API'sinden veya hizmetinden form verilerini alırken, kontrolü yeni değerine güncellemek ve eski değeri tamamen değiştirmek için setValue() yöntemini kullanın.
Aşağıdaki örnek, setValue() yöntemini kullanarak kontrolün değerini Nancy olarak güncellemek için bileşen sınıfına bir yöntem ekler.
name-editor.component.ts (update value)
updateName() {
this.name.setValue('Nancy');
}
Bir ad güncellemesini simüle etmek için şablonu bir düğmeyle güncelleyin. Update Name düğmesine tıkladığınızda, form kontrol öğesine girilen değer geçerli değeri olarak yansıtılır.
name-editor.component.html (update value)
<button type="button" (click)="updateName()">Update Name</button>
Form modeli kontrol için doğruluk kaynağıdır, bu nedenle düğmeye tıkladığınızda girdinin değeri bileşen sınıfı içinde değiştirilir ve geçerli değerini geçersiz kılar.
HELPFUL: Bu örnekte tek bir kontrol kullanıyorsunuz.
setValue() yöntemini bir form grubu veya form dizisi örneğiyle kullanırken, değerin grubun veya dizinin yapısıyla eşleşmesi gerekir.
Form kontrollerini gruplama
Formlar genellikle birbiriyle ilişkili birkaç kontrol içerir. Reaktif formlar, birden fazla ilişkili kontrolü tek bir girdi formunda gruplamak için iki yol sunar.
| Form grupları | Ayrıntılar |
|---|---|
| Form grubu | Birlikte yönetebileceğiniz sabit bir kontrol kümesi ile bir form tanımlar. Form grubu temelleri bu bölümde tartışılmaktadır. Daha karmaşık formlar oluşturmak için form gruplarını iç içe yerleştirebilirsiniz. |
| Form dizisi | Çalışma zamanında kontroller ekleyip kaldırabileceğiniz dinamik bir form tanımlar. Daha karmaşık formlar oluşturmak için form dizilerini de iç içe yerleştirebilirsiniz. Bu seçenek hakkında daha fazla bilgi için Dinamik formlar oluşturma bölümüne bakın. |
Bir form kontrol örneğinin tek bir girdi alanı üzerinde kontrol sağlaması gibi, bir form grubu örneği de bir form kontrol örnekleri grubunun form durumunu takip eder (örneğin, bir form). Form grubu oluşturulurken, form grubundaki her kontrol ada göre takip edilir. Aşağıdaki örnek, birden fazla form kontrol örneğinin tek bir grupta nasıl yönetileceğini gösterir.
Bir ProfileEditor bileşeni oluşturun ve @angular/forms paketinden FormGroup ve FormControl sınıflarını içe aktarın.
ng generate component ProfileEditor
profile-editor.component.ts (imports)
import {FormGroup, FormControl, ReactiveFormsModule} from '@angular/forms';
@Component({
selector: 'app-profile-editor',
templateUrl: './profile-editor.component.html',
styleUrls: ['./profile-editor.component.css'],
imports: [ReactiveFormsModule],
})
export class ProfileEditorComponent {
Bu bileşene bir form grubu eklemek için aşağıdaki adımları izleyin.
- Bir
FormGroupörneği oluşturun. FormGroupmodelini ve görünümü ilişkilendirin.- Form verilerini kaydedin.
-
Bir FormGroup örneği oluşturun
Bileşen sınıfında
profileFormadlı bir özellik oluşturun ve özelliğin değerini yeni bir form grubu örneği olarak ayarlayın. Form grubunu başlatmak için yapıcıya, adlandırılmış anahtarları kontrollerine eşleyen bir nesne sağlayın.Profil formu için,
firstNamevelastNameadlarıyla iki form kontrol örneği ekleyinprofile-editor.component.ts (form group)
import {Component} from '@angular/core'; import {FormGroup, FormControl, ReactiveFormsModule} from '@angular/forms'; @Component({ selector: 'app-profile-editor', templateUrl: './profile-editor.component.html', styleUrls: ['./profile-editor.component.css'], imports: [ReactiveFormsModule], }) export class ProfileEditorComponent { profileForm = new FormGroup({ firstName: new FormControl(''), lastName: new FormControl(''), }); }Bireysel form kontrolleri artık bir grup içinde toplanmıştır. Bir
FormGroupörneği, model değerini gruptaki her kontrolün değerlerinden oluşan bir nesne olarak sağlar. Bir form grubu örneği, bir form kontrol örneğiyle aynı özelliklere (örneğinvalueveuntouched) ve yöntemlere (örneğinsetValue()) sahiptir. -
FormGroup modelini ve görünümünü ilişkilendirin
Bir form grubu, kontrollerinin her biri için durum ve değişiklikleri takip eder, bu nedenle kontrollerden biri değişirse, üst kontrol de yeni bir durum veya değer değişikliği yayar. Grubun modeli, üyelerinden sürdürülür. Modeli tanımladıktan sonra, görünümdeki modeli yansıtmak için şablonu güncellemeniz gerekir.
profile-editor.component.html (template form group)
<form [formGroup]="profileForm"> <label for="first-name">First Name: </label> <input id="first-name" type="text" formControlName="firstName" /> <label for="last-name">Last Name: </label> <input id="last-name" type="text" formControlName="lastName" /> </form>Bir form grubunun bir kontrol grubunu içermesi gibi, profileForm
FormGroup'u,FormGroupdirektifiyleformöğesine bağlanır ve model ile girdileri içeren form arasında bir iletişim katmanı oluşturur.FormControlNamedirektifi tarafından sağlananformControlNamegirdisi, her bireysel girdiyiFormGroup'ta tanımlanan form kontrolüne bağlar. Form kontrolleri ilgili öğeleriyle iletişim kurar. Ayrıca değişiklikleri, model değeri için doğruluk kaynağını sağlayan form grubu örneğine de iletirler. -
Form verilerini kaydedin
ProfileEditorbileşeni kullanıcıdan girdi kabul eder, ancak gerçek bir senaryoda form değerini yakalamak ve bileşen dışında daha fazla işlem için kullanılabilir hale getirmek istersiniz.FormGroupdirektifi,formöğesi tarafından yayılansubmitolayını dinler ve bir geri çağırma fonksiyonuna bağlayabileceğiniz birngSubmitolayı yayar.onSubmit()geri çağırma yöntemiyleformetiketine birngSubmitolay dinleyicisi ekleyin.profile-editor.component.html (submit event)
<form [formGroup]="profileForm" (ngSubmit)="onSubmit()">ProfileEditorbileşenindekionSubmit()yöntemi,profileForm'un geçerli değerini yakalar. Formu kapsüllenmiş tutmak ve form değerini bileşen dışında sağlamak içinoutput()kullanın. Aşağıdaki örnek, tarayıcı konsoluna bir mesaj kaydetmek içinconsole.warnkullanır.profile-editor.component.ts (submit method)
onSubmit() { // TODO: Use output() with form value console.warn(this.profileForm.value); }submitolayı, yerleşik DOM olayı kullanılarakformetiketi tarafından yayılır.submittüründe bir düğmeye tıklayarak olayı tetiklersiniz. Bu, kullanıcının tamamlanmış formu göndermek için Enter tuşuna basmasına olanak tanır.Form gönderimini tetiklemek için formun altına bir düğme eklemek üzere bir
buttonöğesi kullanın.profile-editor.component.html (submit button)
<p>Complete the form to enable button.</p> <button type="submit" [disabled]="!profileForm.valid">Submit</button>Önceki kod parçacığındaki düğme,
profileFormgeçersiz olduğunda düğmeyi devre dışı bırakmak için kendisine bağlı birdisabledbağlamasına da sahiptir. Henüz herhangi bir doğrulama yapmıyorsunuz, bu nedenle düğme her zaman etkindir. Temel form doğrulama, Form girdisini doğrulama bölümünde ele alınmaktadır. -
Bileşeni görüntüleyin
Formu içeren
ProfileEditorbileşenini görüntülemek için, onu bir bileşen şablonuna ekleyin.app.component.html (profile editor)
<app-profile-editor />ProfileEditor, form grubu örneği içindekifirstNamevelastNamekontrolleri için form kontrol örneklerini yönetmenize olanak tanır.İç içe form grupları oluşturma
Form grupları, alt öğe olarak hem bireysel form kontrol örneklerini hem de diğer form grubu örneklerini kabul edebilir. Bu, karmaşık form modellerinin oluşturulmasını kolaylaştırır ve mantıksal olarak birlikte gruplandırır.
Karmaşık formlar oluştururken, bilgilerin farklı alanlarını daha küçük bölümlerde yönetmek daha kolaydır. İç içe yerleştirilmiş bir form grubu örneği kullanmak, büyük form gruplarını daha küçük, daha yönetilebilir gruplara bölmenize olanak tanır.
Daha karmaşık formlar oluşturmak için aşağıdaki adımları kullanın.
- İç içe bir grup oluşturun.
- İç içe formu şablonda gruplayın.
Bazı bilgi türleri doğal olarak aynı gruba düşer. Bir ad ve adres, bu tür iç içe grupların tipik örnekleridir ve aşağıdaki örneklerde kullanılmaktadır.
`profileForm`'da iç içe bir grup oluşturmak için, form grubu örneğine iç içe bir `address` öğesi ekleyin. profile-editor.component.ts (nested form group)
import {Component} from '@angular/core'; import {FormGroup, FormControl, ReactiveFormsModule} from '@angular/forms'; @Component({ selector: 'app-profile-editor', templateUrl: './profile-editor.component.html', styleUrls: ['./profile-editor.component.css'], imports: [ReactiveFormsModule], }) export class ProfileEditorComponent { profileForm = new FormGroup({ firstName: new FormControl(''), lastName: new FormControl(''), address: new FormGroup({ street: new FormControl(''), city: new FormControl(''), state: new FormControl(''), zip: new FormControl(''), }), }); }Bu örnekte,
address groupmevcutfirstNamevelastNamekontrollerini yenistreet,city,statevezipkontrolleriyle birleştirir. Form grubundakiaddressöğesi, form grubundaki genelprofileFormöğesinin bir alt öğesi olmasına rağmen, değer ve durum değişiklikleri için aynı kurallar geçerlidir. İç içe form grubundaki durum ve değer değişiklikleri, üst form grubuna yayılır ve genel modelle tutarlılığı korur. -
İç içe formu şablonda gruplandırın
Bileşen sınıfındaki modeli güncelledikten sonra, form grubu örneğini ve girdi öğelerini bağlamak için şablonu güncelleyin.
street,city,statevezipalanlarını içerenaddressform grubunuProfileEditorşablonuna ekleyin.profile-editor.component.html (template nested form group)
<div formGroupName="address"> <h2>Address</h2> <label for="street">Street: </label> <input id="street" type="text" formControlName="street" /> <label for="city">City: </label> <input id="city" type="text" formControlName="city" /> <label for="state">State: </label> <input id="state" type="text" formControlName="state" /> <label for="zip">Zip Code: </label> <input id="zip" type="text" formControlName="zip" /> </div>ProfileEditorformu tek bir grup olarak görüntülenir, ancak model mantıksal gruplama alanlarını temsil etmek üzere daha ayrıntılı olarak bölünmüştür.Form grubu örneğinin değerini bileşen şablonunda
valueözelliği veJsonPipekullanarak görüntüleyin.
Veri modelinin bölümlerini güncelleme
Birden fazla kontrol içeren bir form grubu örneğinin değerini güncellerken, modelin yalnızca belirli bölümlerini güncellemek isteyebilirsiniz. Bu bölüm, form kontrol veri modelinin belirli bölümlerinin nasıl güncelleneceğini kapsar.
Model değerini güncellemenin iki yolu vardır:
| Yöntemler | Ayrıntılar |
|---|---|
setValue() |
Bireysel bir kontrol için yeni bir değer ayarlayın. setValue() yöntemi, form grubunun yapısına kesinlikle uyar ve kontrolün tüm değerini değiştirir. |
patchValue() |
Form modelinde değişen nesne içinde tanımlanan özellikleri değiştirin. |
setValue() yönteminin katı kontrolleri, karmaşık formlardaki iç içe yerleştirme hatalarını yakalamaya yardımcı olurken, patchValue() bu hatalarda sessizce başarısız olur.
ProfileEditorComponent'te, kullanıcı için ad ve sokak adresini güncellemek üzere updateProfile yöntemini aşağıdaki örnekle kullanın.
profile-editor.component.ts (patch value)
updateProfile() {
this.profileForm.patchValue({
firstName: 'Nancy',
address: {
street: '123 Drew Street',
},
});
}
Kullanıcı profilini talep üzerine güncellemek için şablona bir düğme ekleyerek bir güncellemeyi simüle edin.
profile-editor.component.html (update value)
<button type="button" (click)="updateProfile()">Update Profile</button>
Kullanıcı düğmeye tıkladığında, profileForm modeli firstName ve street için yeni değerlerle güncellenir. street'in address özelliği içinde bir nesne olarak sağlandığına dikkat edin.
Bu gereklidir çünkü patchValue() yöntemi güncellemeyi model yapısına göre uygular.
patchValue() yalnızca form modelinin tanımladığı özellikleri günceller.
Kontrol oluşturmak için FormBuilder hizmetini kullanma
Birden fazla formla uğraşırken form kontrol örneklerini manuel olarak oluşturmak tekrarlayıcı hale gelebilir.
FormBuilder hizmeti, kontroller oluşturmak için kullanışlı yöntemler sağlar.
Bu hizmetten yararlanmak için aşağıdaki adımları kullanın.
FormBuildersınıfını içe aktarın.FormBuilderhizmetini enjekte edin.- Form içeriklerini oluşturun.
Aşağıdaki örnekler, form kontrol ve form grubu örnekleri oluşturmak için form oluşturucu hizmetini kullanmak üzere ProfileEditor bileşenini nasıl yeniden düzenleyeceğinizi gösterir.
-
FormBuilder sınıfını içe aktarın
@angular/formspaketindenFormBuildersınıfını içe aktarın.profile-editor.component.ts (import)
import {FormBuilder, ReactiveFormsModule} from '@angular/forms'; -
FormBuilder servisini enjekte edin
FormBuilderhizmeti, reaktif formlar modülünden enjekte edilebilen bir sağlayıcıdır. Bu bağımlılığı bileşeninize enjekte etmek içininject()fonksiyonunu kullanın.profile-editor.component.ts (property init)
private formBuilder = inject(FormBuilder); -
Form kontrollerini oluşturun
FormBuilderhizmetinin üç yöntemi vardır:control(),group()vearray(). Bunlar, bileşen sınıflarınızda form kontrolleri, form grupları ve form dizileri dahil olmak üzere örnekler oluşturmak için fabrika yöntemleridir.profileFormkontrollerini oluşturmak içingroupyöntemini kullanın.profile-editor.component.ts (form builder)
profileForm = this.formBuilder.group({ firstName: [''], lastName: [''], address: this.formBuilder.group({ street: [''], city: [''], state: [''], zip: [''], }), });Önceki örnekte, modeldeki özellikleri tanımlamak için aynı nesneyle
group()yöntemini kullanırsınız. Her kontrol adının değeri, dizideki ilk öğe olarak başlangıç değerini içeren bir dizidir.TIP: Kontrolü yalnızca başlangıç değeriyle tanımlayabilirsiniz, ancak kontrolleriniz senkron veya asenkron doğrulamaya ihtiyaç duyuyorsa, dizide ikinci ve üçüncü öğe olarak senkron ve asenkron doğrulayıcıları ekleyin. Örnekleri manuel olarak oluşturma ile form oluşturucuyu kullanmayı karşılaştırın.
Form girdisini doğrulama
Form doğrulama, kullanıcı girdisinin eksiksiz ve doğru olmasını sağlamak için kullanılır. Bu bölüm, bir form kontrolüne tek bir doğrulayıcı eklemeyi ve genel form durumunu görüntülemeyi kapsar. Form doğrulama, Form Doğrulama kılavuzunda daha kapsamlı olarak ele alınmaktadır.
Form doğrulama eklemek için aşağıdaki adımları kullanın.
- Form bileşeninize bir doğrulayıcı fonksiyonu içe aktarın.
- Doğrulayıcıyı formdaki alana ekleyin.
- Doğrulama durumunu yönetmek için mantık ekleyin.
En yaygın doğrulama, bir alanı zorunlu yapmaktır.
Aşağıdaki örnek, firstName kontrolüne zorunlu doğrulama eklemeyi ve doğrulama sonucunu görüntülemeyi gösterir.
-
Bir doğrulayıcı fonksiyonu içe aktarın
Reaktif formlar, yaygın kullanım durumları için bir dizi doğrulayıcı fonksiyon içerir. Bu fonksiyonlar, doğrulanacak bir kontrol alır ve doğrulama kontrolüne göre bir hata nesnesi veya null değer döndürür.
@angular/formspaketindenValidatorssınıfını içe aktarın.profile-editor.component.ts (import)
import {Validators} from '@angular/forms'; -
Bir alanı zorunlu yapın
ProfileEditorbileşeninde,firstNamekontrolü için dizideki ikinci öğe olarakValidators.requiredstatik yöntemini ekleyin.profile-editor.component.ts (required validator)
private formBuilder = inject(FormBuilder); profileForm = this.formBuilder.group({ firstName: ['', Validators.required], lastName: [''], address: this.formBuilder.group({ street: [''], city: [''], state: [''], zip: [''], }), }); -
Form durumunu görüntüleyin
Form kontrolüne zorunlu bir alan eklediğinizde, başlangıç durumu geçersiz olur. Bu geçersiz durum üst form grubu öğesine yayılır ve durumunu geçersiz yapar. Form grubu örneğinin geçerli durumuna
statusözelliği aracılığıyla erişin.profileForm'un geçerli durumunu interpolasyon kullanarak görüntüleyin.profile-editor.component.html (display status)
<p>Form Status: {{ profileForm.status }}</p>Zorunlu
firstNameform kontrolü nedeniyleprofileFormgeçersiz olduğu için Submit düğmesi devre dışıdır.firstNamegirdisini doldurduktan sonra form geçerli hale gelir ve Submit düğmesi etkinleşir.Form doğrulama hakkında daha fazla bilgi için Form Doğrulama kılavuzunu ziyaret edin.
Dinamik form'lar oluşturma
FormArray, herhangi bir sayıda adlandırılmamış kontrolü yönetmek için FormGroup'a bir alternatiftir.
Form grubu örneklerinde olduğu gibi, form dizisi örneklerinden kontrolleri dinamik olarak ekleyip kaldırabilirsiniz ve form dizisi örneğinin değeri ile doğrulama durumu, alt kontrollerinden hesaplanır.
Ancak, her kontrol için ada göre bir anahtar tanımlamanız gerekmez, bu nedenle önceden alt değerlerin sayısını bilmediğinizde bu harika bir seçenektir.
Dinamik bir form tanımlamak için aşağıdaki adımları izleyin.
FormArraysınıfını içe aktarın.- Bir
FormArraykontrolü tanımlayın. FormArraykontrolüne bir getter yöntemiyle erişin.- Form dizisini bir şablonda görüntüleyin.
Aşağıdaki örnek, ProfileEditor'da bir takma adlar dizisini nasıl yöneteceğinizi gösterir.
-
FormArraysınıfını içe aktarınTür bilgisi için kullanmak üzere
@angular/forms'danFormArraysınıfını içe aktarın.FormBuilderhizmeti birFormArrayörneği oluşturmaya hazırdır.profile-editor.component.ts (import)
import {FormArray} from '@angular/forms'; -
Bir
FormArraykontrolü tanımlayınBir form dizisini sıfırdan çoğa kadar herhangi bir sayıda kontrol ile başlatabilirsiniz, bunları bir dizide tanımlayarak. Form dizisini tanımlamak için
profileFormform grubu örneğine biraliasesözelliği ekleyin.Diziyi tanımlamak için
FormBuilder.array()yöntemini ve diziyi bir başlangıç kontrolüyle doldurmak içinFormBuilder.control()yöntemini kullanın.profile-editor.component.ts (aliases form array)
private formBuilder = inject(FormBuilder); profileForm = this.formBuilder.group({ firstName: ['', Validators.required], lastName: [''], address: this.formBuilder.group({ street: [''], city: [''], state: [''], zip: [''], }), aliases: this.formBuilder.array([this.formBuilder.control('')]), });Form grubu örneğindeki aliases kontrolü artık tek bir kontrolle doldurulmuştur ve dinamik olarak daha fazla kontrol eklenene kadar böyle kalır.
-
FormArraykontrolüne erişinBir getter, form dizisi örneğindeki takma adlara, her örneği almak için
profileForm.get()yöntemini tekrarlamaya kıyasla erişim sağlar. Form dizisi örneği, bir dizideki tanımlanmamış sayıda kontrolü temsil eder. Bir kontrole getter aracılığıyla erişmek uygundur ve ek kontroller için tekrarlanması kolaydır.Üst form grubundan alias form dizisi kontrolünü almak üzere bir
aliasessınıf özelliği oluşturmak için getter sözdizimini kullanın.profile-editor.component.ts (aliases getter)
get aliases() { return this.profileForm.get('aliases') as FormArray; }Döndürülen kontrol
AbstractControltüründe olduğundan, form dizisi örneği için yöntem sözdizimine erişmek üzere açık bir tür sağlamanız gerekir. Alias form dizisine dinamik olarak bir alias kontrolü eklemek için bir yöntem tanımlayın.FormArray.push()yöntemi kontrolü diziye yeni bir öğe olarak ekler ve ayrıca birden fazla kontrolü aynı anda kaydetmek için FormArray.push() yöntemine bir kontrol dizisi de iletebilirsiniz.profile-editor.component.ts (add alias)
addAlias() { this.aliases.push(this.formBuilder.control('')); }Şablonda, her kontrol ayrı bir girdi alanı olarak görüntülenir.
-
Form dizisini şablonda görüntüleyin
Form modelinizdeki takma adları eklemek için bunları şablona eklemeniz gerekir.
FormGroupNameDirectivetarafından sağlananformGroupNamegirdisine benzer şekilde,formArrayNameform dizisi örneğinden şablonaFormArrayNameDirectiveile iletişimi bağlar.formGroupNameöğesini kapatan<div>'den sonra aşağıdaki şablon HTML'sini ekleyin.profile-editor.component.html (aliases form array template)
<div formArrayName="aliases"> <h2>Aliases</h2> <button type="button" (click)="addAlias()">+ Add another alias</button> @for (alias of aliases.controls; track $index; let i = $index) { <div> <!-- The repeated alias template --> <label for="alias-{{ i }}">Alias:</label> <input id="alias-{{ i }}" type="text" [formControlName]="i" /> </div> } </div>@forbloğu, aliases form dizisi örneği tarafından sağlanan her form kontrol örneği üzerinde yineleme yapar. Form dizisi öğeleri adlandırılmamış olduğundan, diziniideğişkenine atarsınız veformControlNamegirdisine bağlamak için her kontrole iletirsiniz.Her yeni alias örneği eklendiğinde, yeni form dizisi örneğine dizine göre kontrolü sağlanır. Bu, kök kontrolün durumunu ve değerini hesaplarken her bireysel kontrolü takip etmenize olanak tanır.
NOTE: Zoneless uygulamalarda, bir reaktif form modelini değiştirmek (örneğin
FormArray.push()çağırmak) bileşen değişiklik algılamasını otomatik olarak zamanlamaz. Şablonunuzaliases.controlsgibi yapısal model değişikliklerine bağlıysa, bileşenin Angular'a değişiklik algılamasını çalıştırmasını bildirdiğinden emin olun; örneğin bir form observable'ınıChangeDetectorRef.markForCheck()ile köprüleyerek:import {ChangeDetectorRef, Component, inject} from '@angular/core'; import {takeUntilDestroyed} from '@angular/core/rxjs-interop'; @Component({ /* ... */ }) export class ProfileEditor { private readonly cdr = inject(ChangeDetectorRef); constructor() { this.profileForm.valueChanges .pipe(takeUntilDestroyed()) .subscribe(() => this.cdr.markForCheck()); } } -
Bir takma ad ekleyin
Başlangıçta form bir
Aliasalanı içerir. Başka bir alan eklemek için Add Alias düğmesine tıklayın. Ayrıca şablonun altındakiForm Valuetarafından bildirilen takma adlar dizisini de doğrulayabilirsiniz. Her takma ad için bir form kontrol örneği yerine, ek alanlarla başka bir form grubu örneği oluşturabilirsiniz. Her öğe için bir kontrol tanımlama süreci aynıdır.
Üst düzey form dizileri için FormArrayDirective kullanma
Bir FormArray'i FormArrayDirective kullanarak doğrudan bir <form> öğesine bağlayabilirsiniz.
Bu, form üst düzey bir FormGroup kullanmadığında ve dizinin kendisi tam form modelini temsil ettiğinde kullanışlıdır.
import {Component} from '@angular/core';
import {FormArray, FormControl} from '@angular/forms';
@Component({
selector: 'form-array-example',
template: `
<form [formArray]="form">
@for (control of form.controls; track $index) {
<input [formControlName]="$index" />
}
</form>
`,
})
export class FormArrayExampleComponent {
controls = [new FormControl('fish'), new FormControl('cat'), new FormControl('dog')];
form = new FormArray(this.controls);
}
Birleşik kontrol durumu değişiklik olayları
Tüm form kontrolleri, AbstractControl (FormControl, FormGroup, FormArray ve FormRecord) üzerindeki events observable'ı aracılığıyla tek bir birleşik kontrol durum değişikliği olayları akışı sunar.
Bu birleşik akış, değer, durum, pristine, touched ve reset durum değişikliklerine ve ayrıca submit gibi form düzeyinde eylemlere tepki vermenize olanak tanır; böylece birden fazla observable bağlamak yerine tek bir abonelikle tüm güncellemeleri yönetebilirsiniz.
Olay türleri
events tarafından yayılan her öğe, belirli bir olay sınıfının bir örneğidir:
ValueChangeEvent-- kontrolün değeri değiştiğinde.StatusChangeEvent-- kontrolün doğrulama durumuFormControlStatusdeğerlerinden birine (VALID,INVALID,PENDINGveyaDISABLED) güncellendiğinde.PristineChangeEvent-- kontrolün pristine/dirty durumu değiştiğinde.TouchedChangeEvent-- kontrolün touched/untouched durumu değiştiğinde.FormResetEvent-- bir kontrol veya form,reset()API'si veya yerel bir eylem aracılığıyla sıfırlandığında.FormSubmittedEvent-- form gönderildiğinde.
Tüm olay sınıfları ControlEvent'i genişletir ve değişikliği başlatan AbstractControl'e bir source referansı içerir; bu büyük formlarda kullanışlıdır.
import {Component} from '@angular/core';
import {
FormControl,
ValueChangeEvent,
StatusChangeEvent,
PristineChangeEvent,
TouchedChangeEvent,
FormResetEvent,
FormSubmittedEvent,
ReactiveFormsModule,
FormGroup,
} from '@angular/forms';
@Component({
/*...*/
})
export class UnifiedEventsBasicComponent {
form = new FormGroup({
username: new FormControl(''),
});
constructor() {
this.form.events.subscribe((e) => {
if (e instanceof ValueChangeEvent) {
console.log('Value changed to: ', e.value);
}
if (e instanceof StatusChangeEvent) {
console.log('Status changed to: ', e.status);
}
if (e instanceof PristineChangeEvent) {
console.log('Pristine status changed to: ', e.pristine);
}
if (e instanceof TouchedChangeEvent) {
console.log('Touched status changed to: ', e.touched);
}
if (e instanceof FormResetEvent) {
console.log('Form was reset');
}
if (e instanceof FormSubmittedEvent) {
console.log('Form was submitted');
}
});
}
}
Belirli olayları filtreleme
Yalnızca bir olay türü alt kümesine ihtiyacınız olduğunda RxJS operatörlerini tercih edin.
import {filter} from 'rxjs/operators';
import {StatusChangeEvent} from '@angular/forms';
control.events
.pipe(filter((e) => e instanceof StatusChangeEvent))
.subscribe((e) => console.log('Status:', e.status));
Birden fazla aboneliği birleştirme
Önce
import {combineLatest} from 'rxjs/operators';
combineLatest([control.valueChanges, control.statusChanges]).subscribe(([value, status]) => {
/* ... */
});
Sonra
control.events.subscribe((e) => {
// ValueChangeEvent, StatusChangeEvent vb. olayları yönet
});
NOTE: Değer değişikliğinde, yayılma bu kontrolün değeri güncellendikten hemen sonra gerçekleşir. Bir üst kontrolün değeri (örneğin bu FormControl bir FormGroup'un parçasıysa) daha sonra güncellenir, bu nedenle bu olayın geri çağırmasından bir üst kontrolün değerine (value özelliği kullanarak) erişmek, henüz güncellenmemiş bir değer almanızla sonuçlanabilir. Bunun yerine üst kontrolün events'ine abone olun.
Form kontrol durumunu yönetme
Reaktif formlar, touched/untouched ve pristine/dirty ile kontrol durumunu takip eder. Angular bunları DOM etkileşimleri sırasında otomatik olarak günceller, ancak bunları programatik olarak da yönetebilirsiniz.
markAsTouched -- Bir kontrolü veya formu, değeri değiştirmeyen odaklanma ve odak kaybetme olayları tarafından dokunulmuş olarak işaretler. Varsayılan olarak üst kontrollere yayılır.
// Kullanıcı alandan ayrıldıktan sonra doğrulama hatalarını göster
onEmailBlur() {
const email = this.form.get('email');
email.markAsTouched();
}
markAsUntouched -- Bir kontrolü veya formu dokunulmamış olarak işaretler. Tüm alt kontrollere basamaklanır ve tüm üst kontrollerin dokunulmuş durumunu yeniden hesaplar.
// Başarılı gönderimden sonra form durumunu sıfırla
onSubmitSuccess() {
this.form.markAsUntouched();
this.form.markAsPristine();
}
markAsDirty -- Bir kontrolü veya formu değiştirilmiş olarak işaretler, yani değer değiştirilmiştir. Varsayılan olarak üst kontrollere yayılır.
// Programatik olarak değiştirilen değerleri değiştirilmiş olarak işaretle
autofillAddress() {
const previousAddress = getAddress();
this.form.patchValue(previousAddress, { emitEvent: false });
this.form.markAsDirty();
}
markAsPristine -- Bir kontrolü veya formu saf (pristine) olarak işaretler. Tüm alt kontrolleri saf olarak işaretler ve tüm üst kontrollerin saf durumunu yeniden hesaplar.
// Yeni değişiklikleri takip etmek için kaydettikten sonra pristine durumunu sıfırla
saveForm() {
this.api.save(this.form.value).subscribe(() => {
this.form.markAsPristine();
});
}
markAllAsDirty -- Kontrolü veya formu ve tüm alt kontrollerini değiştirilmiş olarak işaretler.
// İçe aktarılan verileri dirty olarak işaretle
loadData(data: FormData) {
this.form.patchValue(data);
this.form.markAllAsDirty();
}
markAllAsTouched -- Kontrolü veya formu ve tüm alt kontrollerini dokunulmuş olarak işaretler. Tüm form genelinde doğrulama hatalarını göstermek için kullanışlıdır.
// Gönderimden önce tüm doğrulama hatalarını göster
onSubmit() {
if (this.form.invalid) {
this.form.markAllAsTouched();
return;
}
this.saveForm();
}
Olay yayımı ve yayılımını kontrol etme
Form kontrollerini programatik olarak güncellerken, değişikliklerin form hiyerarşisi boyunca nasıl yayılacağı ve olayların yayılıp yayılmayacağı üzerinde hassas kontrole sahipsiniz.
Olay yayımını anlama
Varsayılan olarak emitEvent: true'dur; bir kontrole yapılan herhangi bir değişiklik, valueChanges ve statusChanges observable'ları aracılığıyla olayları yayar. emitEvent: false ayarı bu yayımları bastırır; bu, otomatik kaydetme gibi reaktif davranışları tetiklemeden değerleri programatik olarak ayarlamak, kontroller arasındaki döngüsel güncellemeleri önlemek veya olayların yalnızca sonunda bir kez yayılması gereken toplu güncellemeler yapmak için kullanışlıdır.
@Component({
/* ... */
})
export class BlogPostEditor {
postForm = new FormGroup({
title: new FormControl(''),
content: new FormControl(''),
});
constructor() {
// Kullanıcı her yazdığında taslağı otomatik kaydet
this.postForm.valueChanges.subscribe((formValue) => {
this.autosaveDraft(formValue);
});
}
loadExistingDraft(savedDraft: {title: string; content: string}) {
// Otomatik kaydetmeyi tetiklemeden taslağı geri yükle
this.postForm.setValue(savedDraft, {emitEvent: false});
}
}
Yayılım kontrolünü anlama
Varsayılan olarak onlySelf: false'tur; güncellemeler üst kontrollere basamaklanır ve değerleri ile doğrulama durumlarını yeniden hesaplar. onlySelf: true ayarı güncellemeyi geçerli kontrolle sınırlar ve üst bildirimini engeller. Bu, üst güncellemeyi bir kez manuel olarak tetiklemek istediğiniz toplu işlemler için kullanışlıdır.
updatePostalCodeValidator(country: string) {
const postal = this.addressForm.get('postalCode');
const validators = country === 'US'
? [Validators.maxLength(5)]
: [Validators.maxLength(7)];
postal.setValidators(validators);
postal.updateValueAndValidity({ onlySelf: true, emitEvent: false });
}
HELPFUL: Çalışma zamanında validatorları dinamik olarak yönetmek için Form Doğrulama kılavuzundaki Reaktif formlarda validatorları dinamik olarak yönetme bölümüne bakın.
Form kontrol türlerini daraltmak için yardımcı fonksiyonlar
Angular, bir AbstractControl'ün somut türünü belirlemeye yardımcı olan dört yardımcı fonksiyon sağlar. Bu fonksiyonlar tür koruyucuları olarak hareket eder ve true döndürdüklerinde kontrol türünü daraltır; bu da aynı blok içinde alt tipe özgü özelliklere güvenli bir şekilde erişmenize olanak tanır.
| Yardımcı fonksiyon | Ayrıntılar |
|---|---|
isFormControl |
Kontrol bir FormControl olduğunda true döndürür. |
isFormGroup |
Kontrol bir FormGroup olduğunda true döndürür |
isFormRecord |
Kontrol bir FormRecord olduğunda true döndürür |
isFormArray |
Kontrol bir FormArray olduğunda true döndürür |
Bu yardımcılar, fonksiyon imzası bir AbstractControl alan ancak mantığın belirli bir kontrol türü için tasarlandığı özel doğrulayıcılarda özellikle kullanışlıdır.
import {AbstractControl, isFormArray} from '@angular/forms';
export function positiveValues(control: AbstractControl) {
if (!isFormArray(control)) {
return null; // FormArray değil: doğrulayıcı uygulanabilir değil.
}
// Daraltmadan sonra FormArray'e özgü API'ye güvenle erişilebilir.
const hasNegative = control.controls.some((c) => c.value < 0);
return hasNegative ? {positiveValues: true} : null;
}
Reactive form'lar API özeti
Aşağıdaki tablo, reaktif form kontrollerini oluşturmak ve yönetmek için kullanılan temel sınıfları ve hizmetleri listeler. Tam sözdizimi ayrıntıları için Forms paketi API referans belgelerine bakın.
Sınıflar
| Sınıf | Ayrıntılar |
|---|---|
AbstractControl |
FormControl, FormGroup ve FormArray somut form kontrol sınıfları için soyut temel sınıf. Ortak davranışlarını ve özelliklerini sağlar. |
FormControl |
Bireysel bir form kontrolünün değerini ve geçerlilik durumunu yönetir. <input> veya <select> gibi bir HTML form kontrolüne karşılık gelir. |
FormGroup |
Bir AbstractControl örnekleri grubunun değerini ve geçerlilik durumunu yönetir. Grubun özellikleri, alt kontrollerini içerir. Bileşeninizdeki üst düzey form FormGroup'tur. |
FormArray |
Sayısal olarak indekslenmiş bir AbstractControl örnekleri dizisinin değerini ve geçerlilik durumunu yönetir. |
FormBuilder |
Kontrol örnekleri oluşturmak için fabrika yöntemleri sağlayan enjekte edilebilir bir hizmet. |
FormRecord |
Her biri aynı değer türüne sahip bir FormControl örnekleri koleksiyonunun değerini ve geçerlilik durumunu takip eder. |
Direktifler
| Direktif | Ayrıntılar |
|---|---|
FormControlDirective |
Bağımsız bir FormControl örneğini bir form kontrol öğesine senkronize eder. |
FormControlName |
Mevcut bir FormGroup örneğindeki FormControl'ü ada göre bir form kontrol öğesine senkronize eder. |
FormGroupDirective |
Mevcut bir FormGroup örneğini bir DOM öğesine senkronize eder. |
FormGroupName |
İç içe bir FormGroup örneğini bir DOM öğesine senkronize eder. |
FormArrayName |
İç içe bir FormArray örneğini bir DOM öğesine senkronize eder. |
FormArrayDirective |
Bağımsız bir FormArray örneğini bir DOM öğesine senkronize eder. |