導入
これまでのレッスンでは [value] と (input) を手作りで組み合わせて入力を扱ってきました(レッスン10など)。実務ではもっと多くの入力項目やバリデーション(入力チェック)を扱うため、Angularは専用の仕組み Reactive Forms を用意しています。
説明
ReactiveFormsModule を imports に加えると、FormControl(1つの入力欄を表す)や FormGroup(複数の FormControl をまとめたもの)が使えるようになります。
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-root',
standalone: true,
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form" (ngSubmit)="submit()">
<input formControlName="name" placeholder="お名前" />
<input formControlName="email" placeholder="メールアドレス" />
<button type="submit" [disabled]="form.invalid">送信</button>
</form>
<p *ngIf="form.get('email')?.invalid && form.get('email')?.touched">
メールアドレスの形式が正しくありません
</p>
`,
})
export class AppComponent {
form = new FormGroup({
name: new FormControl('', Validators.required),
email: new FormControl('', [Validators.required, Validators.email]),
});
submit(): void {
console.log(this.form.value);
}
}
flowchart TB fg["FormGroup(フォーム全体)"] fc1["FormControl: name<br/>Validators.required"] fc2["FormControl: email<br/>Validators.required + email"] fg --> fc1 fg --> fc2 fg -->|"form.valid / form.value"| submit["送信処理"]
FormControl… 入力欄1つぶんの値と状態(未入力か・バリデーション通過か・触れたか)を持つオブジェクトです。FormGroup… 複数のFormControlをまとめたもの。まとめてform.validやform.valueを確認できます。[formGroup]="form"とformControlName="name"… テンプレートの<form>とHTMLの入力欄を、クラス側のformに結び付けます。Validators.required/Validators.email… あらかじめ用意されたバリデーションルール。自作の関数を渡すこともできます。- もっと簡易なテンプレート駆動フォーム(
[(ngModel)]を使う方法)もありますが、実務では入力項目が多い画面ほど Reactive Forms が好まれます(テストしやすく、ロジックがクラス側に集まるため)。
まとめ
フォームは「入力欄=FormControl」「まとまり=FormGroup」で表現され、テンプレート側は formGroup/formControlName でクラス側と結び付きます。手元のプロジェクトで ReactiveFormsModule を試してみましょう。