Angularのチュートリアルでは、フォームはngModelで双方向バインドできると学習できますが、
フォームを動的に増減させたい場合や、バリデーションを効かせてエラーメッセージを出すことになりそうな場合は。
リアクティブフォームを使うと便利です。
https://angular.jp/guide/reactive-forms
ただ、ngModelよりも複雑なので、いろんなクラスやメソッドが出てきて、初めて触るとちょっと混乱しがちです。
https://angular.jp/api/forms にはクラスが10個記載されています。
今回は頻出のクラス6つを説明しながらコンポーネントファイルで定義するところまで追っていきます。
Abstruct Control
後述するFormControlとFormGroup、FormArrayの継承元のクラスです。
https://angular.jp/api/forms/AbstractControl
このクラスでは値の検証やバリデーションチェックをしています。
FormGroupのインスタンスに対して指定の方法を誤ってしまうと、
リントで以下のように怒られたりします。
controls does not exist on type AbstractControl
FormGroup, FormControl, FormArray
次はFormGroupとFormControlとFormArrayの説明になります。
リアクティブフォームではフォームの各要素を、
オブジェクトや、配列、プロパティのようなものとして定義して構造化します。
オブジェクトに当たるものがFormGroup、
配列に当たるものがFormArray、
プロパティに当たるものがFormControlです。
https://angular.jp/api/forms/FormGroup
https://angular.jp/api/forms/FormControl
https://angular.jp/api/forms/FormArray
後述するFormBuilderを使った方がシンプルにかけますが、以下のような感じで定義できます。
new FormGroup({})やnew FormControl(”)のようにインスタンスを作って定義することもできますが、
次に書くFormBuilderを使った方がシンプルになります。
FormBuilder
FormBuilder上記のフォーム構造をシンプルに書くことができます。
https://angular.jp/api/forms/FormBuilder
Angularのチュートリアルを参考にした例だと以下のようになります。
import {Validators, FormControl, FormGroup, FormArray, FormBuilder } from '@angular/forms'; ~~ constructor( private fb: FormBuilder ){} ngOnInit() { profileForm = this.fb.group({ // formGroupの設定 firstName: [''], // formControlの設定 lastName: [''], address: this.fb.group({ // 入れ子状にformGroupを設定 street: [''], city: [''], state: [''], zip: ['111-1111'] // 初期値を111-1111として定義 }), aliases: this.fb.array([ // formArrayの設定 this.fb.control(''), this.fb.control('') ]) }); }
Validators
デフォルトで用意されているバリデーションのクラスです。
https://angular.jp/api/forms/Validators
ここに記載のないバリデーションを効かせたい場合は、カスタムバリデーションを作る必要があります。
バリデーションの設定方法は以下の通りです。
import { Validators, FormControl, FormGroup, FormArray, FormBuilder } from '@angular/forms'; ~~ ngOnInit() { profileForm = this.fb.group({ firstName: ['', Validators.required], // バリデーションを1つだけ設定するとき lastName: ['', [Validators.required, Validators.required.maxLength(30)]], // バリデーションを複数つけるときは配列で。 address: this.fb.group({ street: [''], city: [''], state: [''], zip: [''] }), aliases: this.fb.array([ this.fb.control(''), this.fb.control('') ]) }); }
以上でクラス6つの説明とコンポーネントファイルでの定義の説明は終わりです。
validationを任意のタイミングで設定したりということもできますが、それはまた別記事で書いてみようかと思います。
HTML側でも設定が必要なので次はそれを書いてみようかと思います。