コンテンツへスキップ
Angular Reactive Formsのカスタムバリデータを作成する方法

Angular Reactive Formsのカスタムバリデータを作成する方法

このブログ記事では、Angular Reactive Formsでカスタムバリデータを作成する方法を学びます。リアクティブフォームを初めて使用する場合は、ここで最初のAngularリアクティブフォームの作成方法を確認してください。

7min read

このブログ記事では、Angular Reactive Formsでカスタムバリデータを作成する方法を学びます。リアクティブフォームを初めて使用する場合は、ここで最初のAngularリアクティブフォームを作成する方法をご覧ください。

次のリストに示すようなログインフォームがあるとします。現在、フォーム コントロールには検証がアタッチされていません。

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null),
        password: new FormControl(null),
        age: new FormControl(null)
    });
}

ここでは、FormGroupを使用してリアクティブフォームを作成しています。コンポーネントテンプレートでは、次のコードリストに示すようにloginFormをアタッチできます。プロパティ バインドを使用すると、HTML フォーム要素の formGroup プロパティが loginForm に設定され、これらのコントロールの formControlName 値が FormGroup の個々の FormControl プロパティに設定されます。

<form (ngSubmit)='loginUser()' [formGroup]='loginForm' novalidate class="form">
     <input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
     <br />
     <input formControlName='password' type="password" class="form-control" placeholder="Enter Password" />
     <br />
     <input formControlName='age' type="number" class="form-control" placeholder="Enter Age" />
     <br />
     <button [disabled]='loginForm.invalid' class="btn btn-default">Login</button>
 </form>

これにより、アプリケーションでリアクティブフォームが得られます。

これにより、アプリケーションでリアクティブフォームが得られます

Using Validators

Angular、requiredminLengthmaxLengthpatternなど、多くの便利なバリデーターを提供します。 これらのバリデータは、@angular/formsパッケージに付属するValidatorsクラスの一部です。

必要な検証を電子メール コントロールに追加し、maxLength 検証をパスワード コントロールに追加するとします。その方法は次のとおりです。

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null)
    });
}

バリデータを操作するには、必ずコンポーネントクラスにインポートしてください。

import { FormGroup, FormControl, Validators } from '@angular/forms';

テンプレートでは、バリデーターを使用してエラーメッセージを表示または非表示にすることができます。基本的には、get() メソッドを使用して formControl を読み取り、hasError() メソッドを使用してエラーがあるかどうかを確認しています。また、touched プロパティを使用して、formControl がタッチされているかどうかも確認しています。

<input formControlName='email' type="text" class="form-control" placeholder="Enter Email" />
<div class="alert  alert-danger" *ngIf="loginForm.get('email').hasError('required') && loginForm.get('email').touched">
    Email is required
</div>

ユーザーがメールアドレスを入力しない場合、リアクティブフォームには次のようなエラーが表示されます。

ユーザーがメールアドレスを入力しない場合、リアクティブフォームにはエラーが表示されます

Custom Validators

年齢範囲を18歳から45歳にしたいとします。Angular範囲の検証は提供しません。したがって、このためのカスタムバリデーターを作成する必要があります。

Angularでは、カスタムバリデーターの作成は、別の関数を作成するのと同じくらい簡単です。覚えておく必要があるのは、AbstractControl 型の入力パラメーターを 1 つ受け取り、検証が失敗した場合はキーと値のペアのオブジェクトを返すことだけです。

ageRangeValidatorというカスタムバリデーターを作成し、ユーザーが特定の範囲内にある場合にのみ年齢を入力できるようにしてみましょう。

Create a custom validator called ageRangeValidator

最初のパラメーターの型は、FormControl、FormArray、および FormGroup の基本クラスであり、カスタム検証関数に渡されるコントロールの値を読み取ることができるため、AbstractControl です。カスタムバリデーターは、次のいずれかを返します。

  1. 検証が失敗した場合は、キーと値のペアを含むオブジェクトが返されます。keyはエラーの名前で、値は常にブール値 trueです。
  2. 検証が失敗しない場合は、nullを返します。

これで、以下のリストで ageRangeValidatorカスタムバリデーターを実装できます。

function ageRangeValidator(control: AbstractControl): { [key: string]: boolean } | null {
 
    if (control.value !== undefined && (isNaN(control.value) || control.value < 18 || control.value > 45)) {
        return { 'ageRange': true };
    }
    return null;
}

ここでは、バリデーターの最大範囲と最小範囲をハードコーディングしています。次のセクションでは、これらのパラメータを渡す方法を見ていきます。

これで、次のリストに示すように、ageRangeValidatorを年齢コントロールと共に使用できます。ご覧のとおり、配列にカスタムバリデーター関数の名前を追加する必要があります。

ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator])
    });
}

テンプレートでは、カスタムバリデーターを他のバリデーターと同様に使用できます。ageRange検証を使用して、エラー メッセージを表示または非表示にしています。

<input formControlName='age' type="number" class="form-control" placeholder="Enter Age" />
 <div class="alert  alert-danger" *ngIf="loginForm.get('age').dirty && loginForm.get('age').errors && loginForm.get('age').errors.ageRange ">
     Age should be in between 18 to 45 years
 </div>

ユーザーが 18 歳から 45 歳までの年齢を入力しない場合、リアクティブ フォームにはエラーが表示されます。

現在、年齢制御はカスタムバリデーターと連携しています。ageRangeValidator の唯一の問題は、18 歳から 18 歳までの数値のみを検証するハードコードされた年齢範囲です。固定範囲を回避するには、ageRangeValidator に最大年齢と最小年齢を渡す必要があります。

カスタムバリデーターへのパラメーターの受け渡し

Angularカスタムバリデーターは、コントロールの参照以外の追加の入力パラメーターを直接取得しません。追加のパラメータを渡すには、ファクトリ関数内にカスタムバリデーターを追加する必要があります。その後、ファクトリ関数はカスタムバリデーターを返します。

あなたは正しいと聞きました:JavaScriptでは、関数は別の関数を返すことができます

基本的に、カスタムバリデーターにパラメーターを渡すには、次の手順に従う必要があります。

  1. ファクトリ関数を作成し、カスタムバリデーターに渡されるパラメータをこの関数に渡します。
  2. ファクトリ関数の戻り値の型は、@angular/formsの一部であるValidatorFnである必要があります
  3. ファクトリ関数からカスタムバリデータを返します。

ファクトリ関数の構文は次のとおりです。

これで、次のリストに示すように、入力パラメーターを受け入れるように ageRangeValidator をリファクタリングできます。

function ageRangeValidator(min: number, max: number): ValidatorFn {
    return (control: AbstractControl): { [key: string]: boolean } | null => {
        if (control.value !== undefined && (isNaN(control.value) || control.value < min || control.value > max)) {
            return { 'ageRange': true };
        }
        return null;
    };
}

入力パラメータmaxminを使用して、年齢制御を検証しています。これで、ageRangeValidator を年齢制御と共に使用し、以下のリストに示すように max と min の値を渡すことができます。

min = 10;
max = 20;
ngOnInit() {
    this.loginForm = new FormGroup({
        email: new FormControl(null, [Validators.required]),
        password: new FormControl(null, [Validators.required, Validators.maxLength(8)]),
        age: new FormControl(null, [ageRangeValidator(this.min, this.max)])
    });
}

テンプレートでは、カスタムバリデーターを他のバリデーターと同様に使用できます。ageRange検証を使用して、エラーメッセージを表示または非表示にしています。

<input formControlName='age' type="number" class="form-control" placeholder="Enter Age" />
  <div class="alert  alert-danger" *ngIf="loginForm.get('age').dirty && loginForm.get('age').errors && loginForm.get('age').errors.ageRange ">
      Age should be in between {{min}} to {{max}} years
  </div>

この場合、ユーザーが 10 歳から 20 歳までの年齢を入力しないと、次のようなエラー メッセージが表示されます。

この場合、ユーザーが 10 歳から 20 歳までの年齢を入力しないと、エラー メッセージが表示されます

以上で、Angular Reactive Formsのカスタムバリデータを作成する方法をご紹介します。

この投稿が好きですか?

この投稿が気に入ったら、共有してください。また、Angularコンポーネントをまだチェックしていない場合は、必ずチェックしてください。

Ignite UI for Angular

デモを予約