Angularでリアクティブフォームのカスタムバリデーターを作成する方法

提供:Dev Guides
移動先:案内検索

序章

Angularの@angular/formsパッケージには、requiredminLengthmaxLengthpattern。 ただし、検証にさらに複雑なルールまたはカスタムルールを必要とするフォームフィールドが存在する場合があります。 そのような状況では、カスタムバリデーターを使用できます。

AngularでReactiveForms を使用する場合、関数を使用してカスタムバリデーターを定義します。 バリデーターを再利用する必要がない場合は、コンポーネントファイルに関数として直接存在できます。 それ以外の場合、バリデーターを他のコンポーネントで再利用する必要がある場合は、別のファイルに存在する可能性があります。

このチュートリアルでは、URLが特定の条件を満たすかどうかを確認するために、再利用可能なカスタムバリデーターを使用してリアクティブフォームを作成します。

前提条件

このチュートリアルを完了するには、次のものが必要です。

このチュートリアルは、ノードv15.2.1、npm v6.14.8、@angular/core v11.0.0、および@angular/formsv11.0.0で検証されました。

ステップ1-プロジェクトの設定

このチュートリアルでは、@angular/cliで生成されたデフォルトのAngularプロジェクトからビルドします。

npx @angular/cli new angular-reactive-forms-custom-validtor-example --style=css --routing=false --skip-tests

これにより、スタイルが「CSS」(「Sass」、「Less」、「Stylus」ではなく)に設定され、ルーティングがなく、テストがスキップされる新しいAngularプロジェクトが構成されます。

新しく作成されたプロジェクトディレクトリに移動します。

cd angular-reactive-forms-custom-validator-example

リアクティブフォームを操作するには、FormsModuleの代わりにReactiveFormsModuleを使用します。

コードエディタでapp.module.tsを開き、ReactiveFormsModuleを追加します。

src / app / app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    ReactiveFormsModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

この時点で、ReactiveFormsModuleを使用した新しいAngularプロジェクトが作成されているはずです。

ステップ2–カスタムバリデーターを構築する

このチュートリアルのカスタムバリデーターの例では、URL文字列を取得し、httpsプロトコルで始まり、.ioトップレベルドメインで終わることを確認します。

まず、ターミナルでsharedディレクトリを作成します。

mkdir src/shared

次に、この新しいディレクトリに、新しいurl.validator.tsファイルを作成します。 このファイルをコードエディタで開き、次のコード行を追加します。

src / shared / url.validator.ts

import { AbstractControl } from '@angular/forms';

export function ValidateUrl(control: AbstractControl) {
  if (!control.value.startsWith('https') || !control.value.includes('.io')) {
    return { invalidUrl: true };
  }
  return null;
}

このコードは、FormControlFormGroup、およびFormArrayの基本クラスであるNoticeAbstractControlクラスを使用します。 これにより、FormControlの値にアクセスできます。

このコードは、値startsWithhttpsの文字列であるかどうかを確認します。 また、値includes.ioの文字列であるかどうかも確認します。

検証が失敗した場合、エラー名のキーinvalidUrl、および値trueを持つオブジェクトが返されます。

それ以外の場合、検証に合格すると、nullが返されます。

この時点で、カスタムバリデーターを使用する準備が整いました。

ステップ3–カスタムバリデーターの使用

次に、userNamewebsiteUrlを取るフォームを作成します。

app.component.tsを開き、コンテンツを次のコード行に置き換えます。

src / app / app.component.ts

import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { ValidateUrl } from '../shared/url.validator';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  myForm: FormGroup;

  constructor(private fb: FormBuilder) {}

  ngOnInit() {
    this.myForm = this.fb.group({
      userName: ['', Validators.required],
      websiteUrl: ['', [Validators.required, ValidateUrl]]
    });
  }

  saveForm(form: FormGroup) {
    console.log('Valid?', form.valid); // true or false
    console.log('Username', form.value.userName);
    console.log('Website URL', form.value.websiteUrl);
  }
}

このコードでは、websiteUrlフォームコントロールは組み込みのValidators.requiredとカスタムValidateUrlバリデーターの両方を使用します。

ステップ4–テンプレートのエラーにアクセスする

フォームを操作するユーザーは、検証に失敗している値に関するフィードバックが必要になります。 コンポーネントテンプレートでは、カスタムバリデーターの戻り値で定義したキーを使用できます。

app.component.htmlを開き、コンテンツを次のコード行に置き換えます。

src / app / app.component.html

<form [formGroup]="myForm" ngSubmit)="saveForm(myForm)">
  <div>
    <label>
      Username:
      <input formControlName="userName" placeholder="Your username">
    </label>
    <div *ngIf="(
                 myForm.get('userName').dirty ||
                 myForm.get('userName').touched
                ) &&
                myForm.get('userName').invalid"
    >
      Please provide your username.
    </div>
  </div>
  <div>
    <label>
      Website URL:
      <input formControlName="websiteUrl" placeholder="Your website">
    </label>
    <div
      *ngIf="(
              myForm.get('websiteUrl').dirty ||
              myForm.get('websiteUrl').touched
             ) &&
             myForm.get('websiteUrl').invalid"
      >
      Only URLs served over HTTPS and from the .io top-level domain are accepted.
    </div>
  </div>
</form>

この時点で、アプリケーションをコンパイルできます。

npm start

そしてそれをあなたのウェブブラウザで開きます。 userNameおよびwebsiteUrlのフィールドを操作できます。 ValidateUrlのカスタムバリデーターが、httpsおよび.ioの条件を満たす値で期待どおりに機能することを確認します:https://example.io

結論

この記事では、Angularアプリケーションのリアクティブフォーム用に再利用可能なカスタムバリデーターを作成しました。

テンプレート駆動型フォームとリアクティブフォームのカスタムバリデーターの例については、Angularのカスタムフォームバリデーターを参照してください。

Angularについて詳しく知りたい場合は、Angularトピックページで演習とプログラミングプロジェクトを確認してください。