فرم های پیشرفته (Forms Advanced)
در «فرم های واکنشی پیشرفته» مدل داده پیچیده را می سازیم. سپس با «اعتبارسنج» ها کنترل می کنیم. همچنین با patchValue سریع به روزرسانی می کنیم. در نهایت با valueChanges رفتار واکنشی می گیریم.
مبانی فرم های واکنشی پیشرفته
«فرم واکنشی (Reactive Form)» یعنی فرم با مدل جاوااسکریپتی. «گروه فرم (FormGroup)» ظرف چند کنترل است. «آرایه فرم (FormArray)» لیست پویا از کنترل هاست. «اعتبارسنج (Validator)» قانون چک کردن مقدار است.
import { FormBuilder } from '@angular/forms';
import { Validators } from '@angular/forms';
import { FormArray } from '@angular/forms';
const fb = new FormBuilder();
const form = fb.group({
name: ['', Validators.required],
tags: fb.array([
fb.group({ label: ['Angular'] }),
]),
});
(form.get('tags') as FormArray).push(
fb.group({ label: [''] }),
);
گروه ها و آرایه های تو در تو
ابتدا «کنترل های مرتبط» را در یک گروه بگذار. سپس برای لیست ها از آرایه فرم استفاده کن. بنابراین افزودن ردیف بسیار ساده می شود.
import { FormBuilder } from '@angular/forms';
import { FormArray } from '@angular/forms';
const fb = new FormBuilder();
const tags = fb.array([
fb.group({ label: ['Angular'] }),
]);
tags.push(
fb.group({ label: [''] }),
);
نمونه کامل: فرم واکنشی پیشرفته
در این نمونه یک نام و لیست برچسب ها داریم. سپس ردیف ها را پویا اضافه می کنیم. در پایان مقدار فرم را نمایش می دهیم.
import { bootstrapApplication } from '@angular/platform-browser';
import { Component } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { FormBuilder } from '@angular/forms';
import { Validators } from '@angular/forms';
import { FormArray } from '@angular/forms';
import { JsonPipe } from '@angular/common';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, JsonPipe],
template: `
<h3>Advanced Reactive Form</h3>
<form [formGroup]=\"form\" (ngSubmit)=\"submit()\">
<input placeholder=\"Name\" formControlName=\"name\">
<div formArrayName=\"tags\">
<div *ngFor=\"let t of tags.controls; let i = index\" [formGroupName]=\"i\">
<input placeholder=\"Tag\" formControlName=\"label\">
</div>
</div>
<button type=\"button\" (click)=\"addTag()\">Add Tag</button>
<button type=\"submit\">Submit</button>
</form>
<pre>{{ form.value | json }}</pre>
`,
})
class App {
fb = new FormBuilder();
form = this.fb.group({
name: ['', Validators.required],
tags: this.fb.array([
this.fb.group({ label: ['Angular'] }),
]),
});
get tags(): FormArray {
return this.form.get('tags') as FormArray;
}
addTag() {
this.tags.push(
this.fb.group({ label: [''] }),
);
}
submit() {
alert(JSON.stringify(this.form.value));
}
}
bootstrapApplication(App);
راهبردهای اعتبارسنجی
«اعتبارسنج همگام (Sync)» سریع و ساده است. «اعتبارسنج ناهمگام (Async)» برای چک سرور مناسب است. همچنین قبل از Async ورودی را debounce کن.
import { AbstractControl } from '@angular/forms';
import { ValidationErrors } from '@angular/forms';
import { Validators } from '@angular/forms';
import { FormBuilder } from '@angular/forms';
function banned(list: string[]): (c: AbstractControl) => ValidationErrors | null {
return (c: AbstractControl) => {
return list.includes(c.value) ? { banned: true } : null;
};
}
const fb = new FormBuilder();
const control = fb.control('', [Validators.required, banned(['admin'])]);
import { AbstractControl } from '@angular/forms';
import { ValidationErrors } from '@angular/forms';
import { FormBuilder } from '@angular/forms';
function samePassword(group: AbstractControl): ValidationErrors | null {
const pass = group.get('pass')?.value;
const confirm = group.get('confirm')?.value;
return pass === confirm ? null : { mismatch: true };
}
const fb = new FormBuilder();
const form = fb.group(
{ pass: [''], confirm: [''] },
{ validators: samePassword, updateOn: 'blur' },
);
گام های عملی
- فرم را با FormBuilder بساز و گروه بندی کن.
- برای لیست ها یک FormArray قرار بده.
- اعتبارسنج های لازم را اضافه کن.
- برای به روزرسانی جزئی از patchValue استفاده کن.
- به valueChanges گوش کن و منطق واکنشی بساز.
نکته: اگر همه کلیدها را داری، setValue بزن. اما برای تغییر بخشی از مدل، patchValue بهتر است.
جمع بندی سریع
- FormGroup برای ساختاردهی مناسب است.
- FormArray برای ردیف های پویا است.
- patchValue انعطاف بیشتری می دهد.
- updateOn نویز اعتبارسنجی را کم می کند.
- valueChanges منطق زنده می سازد.
مطالب مرتبط: فرم های واکنشی پیشرفته، اینترسپتورهای HTTP، روتر پیشرفته.