前回からの続きです。
今回は残りのバリデーションとエラーメッセージ部分を行います。
標準のinputなどのフォームと同様の使い方ができること- 入力必須のバリデーションが行われること
- 未入力の場合にエラーメッセージを表示されること
##Validationを設定する
validationを設定するには以下の2点を実装します。
- validateメソッド
- NG_VALIDATORSをDIする
validateメソッドを追加する
標準のバリデーションルールを使う場合は以下のように実装します。
validate(ctrl: AbstractControl){
return Validators.required(ctrl);
}
自分でバリデーションルールを作る場合には、以下のように実装します。validの場合はnullを返し、invalidの場合はObjectを返します。Objectのkey名は自由です。
validate(ctrl: AbstractControl){
if(ctrl.value){
return null;
}else{
return {required: true}
}
}
NG_VALIDATORSをDIする
valueAccessorの時と同様にproviderを設定する
{
provide: NG_VALIDATORS,
multi: true,
useExisting: RequiredTextComponent,
},
ここまでのDEMO
https://stackblitz.com/edit/angular-custom-form-control-k-dby8bo
エラーメッセージを表示する
エラーメッセージを表示する場合には、コンポーネントに設定されているFormControlにアクセスできるようにする必要があります。
constructor(@Self() public controlDir: NgControl){
controlDir.valueAccessor = this;
control.setValidators(this.validate);
control.updateValueAndValidity();
}
これはproveiderにNG_VALUE_ACCESSORとNG_VALIDATORSをDIしているのと同じことを行っています。
そのため、providersに設定した部分は外します。
ちなみに、NgControlはNgModelやFormControlNameのスーパークラスです。
/* providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: RequiredTextComponent,
multi: true,
},
{
provide: NG_VALIDATORS,
multi: true,
useExisting: RequiredTextComponent,
},
],
*/
次にView側でcontrolを使ってエラーメッセージを表示させます
<input type="text" #input
(input)="onChange($event.target.value)"
(blur)="onTouched()"
[disabled]="disabled"
[ngClass]="{error: controlDir && !controlDir.control.valid}">
<div class="error"
*ngIf="controlDir && !controlDir.control.valid">
This field is invalid.
</div>
おわりに
カスタムフォームを作る方法は以上です。
これを応用としてradioボタンを作ったれいネストしたフォームを作る方法を次回書こうかと思います。
標準のinputなどのフォームと同様の使い方ができること入力必須のバリデーションが行われること未入力の場合にエラーメッセージを表示されること
ここまでのDEMO
https://stackblitz.com/edit/angular-custom-form-control-k-c6htnz