Angularには、フォームを作成する方法として「テンプレート駆動フォーム(テンプレート駆動型)」と「リアクティブフォーム(モデル駆動型)」の2種類があります。
この記事では、リアクティブフォームの中でも最も基本的な構成であるFormControl
の使い方について、サンプルコードを用いてわかりやすく解説します。
【ReactiveForms】FormControlの使い方
準備:ReactiveFormsModuleをインポートする
まず、Angularでリアクティブフォームを使うには、ReactiveFormsModule
をアプリケーションに読み込む必要があります。そのため、まずapp.module.ts
にReactiveFormsModule
を追加しましょう。
// src/app/app.module.ts
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [
BrowserModule,
ReactiveFormsModule, // ← リアクティブフォーム機能を使うために必要!
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {}
ReactiveFormsModule
をインポートすると、[formControl]
ディレクティブなど、リアクティブフォームで使う機能が利用できるようになります。
FormControlを定義する
フォームの入力欄を制御するためには、FormControl
を使います。以下に実装例を示します。
// src/app/app.component.ts
import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-root',
template: `
<!-- nameというフォームコントロールをinputタグと連携 -->
<input type="text" [formControl]="name" />
<!-- フォームコントロール値の表示 -->
<p>現在の値:{{ name.value }}</p>
<!-- フォームコントロール値の置換 -->
<button type="button" (click)="updateName()">名前を「Taro」に更新</button>
`,
})
export class AppComponent {
name = new FormControl(''); // ← 初期値は空文字
updateName() {
this.name.setValue('Taro');
}
}
name = new FormControl('');
- フォームコントロールのインスタンス
name
を作成しています。初期値は空の文字列(''
)です。
- フォームコントロールのインスタンス
<input type="text" [formControl]="name" />
name
というフォームコントロールとinput
タグをバインドしています。これで双方向バインディングが自動で行われます。
フォームコントロール値の表示方法
フォームに入力した値をリアルタイムで表示することもできます。以下のコードでは、name.value
を使って、現在の入力値を表示しています。入力フィールドに文字を入力すると、入力された値がリアルタイムに反映されます。
<p>現在の値:{{ name.value }}</p>
フォームコントロール値の置換方法(setValue)
プログラムからフォームコントロールの値を更新するには、setValue()
メソッドを使います。以下のサンプルコードのように実装した場合、ボタンをクリックすると、updateName()
が実行され、name
の値が'Taro'
に置き換えられます。
<button type="button" (click)="updateName()">名前を「Taro」に更新</button>
// src/app/app.component.ts
updateName() {
this.name.setValue('Taro');
}
【補足】バリデーションの方法
バリデーションを設定したい場合は、FormControl
の第2引数にバリデーション関数を渡します。
// src/app/app.component.ts
import { Component } from '@angular/core';
import {
AbstractControl,
FormControl,
ValidationErrors,
ValidatorFn,
Validators,
} from '@angular/forms';
@Component({
selector: 'app-root',
template: `
<!-- nameというフォームコントロールをinputタグと連携 -->
<input type="text" [formControl]="name" />
<!-- エラーメッセージの表示 -->
<div *ngIf="name.invalid && (name.dirty || name.touched)">
<div *ngIf="name.hasError('required')">名前は必須です。</div>
<div *ngIf="name.hasError('minlength')">
名前は4文字以上で入力してください。
</div>
<div *ngIf="name.hasError('forbiddenName')">
「Bob」という名前は禁止されています。
</div>
</div>
`,
})
export class AppComponent {
// バリデーション付きのFormControl
name = new FormControl('', [
Validators.required, // 入力必須
Validators.minLength(4), // 4文字以上
this.forbiddenNameValidator(/^bob$/i), // 「Bob」は禁止
]);
// カスタムバリデーターの定義
forbiddenNameValidator(nameRe: RegExp): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const forbidden = nameRe.test(control.value);
return forbidden ? { forbiddenName: { value: control.value } } : null;
};
}
}
Angularのリアクティブフォームでは、以下のような組み込みバリデータが用意されています。
バリデーション | 内容 |
---|---|
Validators.required | 入力必須 |
Validators.minLength(n) | 最小文字数n以上 |
Validators.maxLength(n) | 最大文字数n以下 |
Validators.email | メール形式であること |
Validators.pattern() | 正規表現にマッチすること |
また、カスタムバリデータも作成することができます。関数forbiddenNameValidator()
は、FormControl
の値が特定の文字列(この場合 "bob"
)に一致した場合にエラーを返します。正規表現/^bob$/i
で大文字小文字を区別せずに判定しています。
エラーメッセージについて
<div *ngIf="name.invalid && (name.dirty || name.touched)">
上記のコードでは、次のような場合にだけエラーが表示されるようにしています。
invalid
- バリデーションエラーがある場合
dirty
ortouched
- ユーザーが入力欄を操作済みの場合
dirty
:値が変更された状態である場合touched
:フォーカスが当たった後に離れた状態である場合
- ユーザーが入力欄を操作済みの場合
hasError()
name.hasError('required')
: 入力必須チェックエラー(空文字だった場合)name.hasError('minlength')
: 最小文字数エラーname.hasError('forbiddenName')
: カスタムバリデーションエラー
【補足】FormGroupやFormArrayの活用も!
今回はリアクティブフォームの基本であるFormControl
の使い方を解説しましたが、実際のフォームでは複数の入力欄をまとめて管理したくなることも多いです。そんなときは、FormGroup
やFormArray
といったクラスを使うことで、複数のFormControl
をグループ化して、より複雑なフォームを簡単に扱えるようになります。
FormGroup の簡単な例
this.profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
});
<form [formGroup]="profileForm">
<input type="text" formControlName="firstName" />
<input type="text" formControlName="lastName" />
</form>
今後、フォームを扱う機会が増えてきたら、ぜひFormGroup
やFormArray
、FormBuilder
などの機能も学んでみてください!
本記事のまとめ
この記事では、Angularのリアクティブフォームの基本であるFormControl
の使い方について、以下の内容を説明しました。
ReactiveFormsModule
のインポート方法FormControl
の定義とバインディング方法- 入力値の表示方法と更新方法
- バリデーションの設定方法
お読み頂きありがとうございました。