アプリケーションでは、アカウントの作成・ログインなど、フォームを開発する場面が多いかと思います。
今回はAngularのプロジェクトでngFormを使用したテンプレート駆動フォームを実装について整理していこうと思います。
テンプレート駆動フォームとは
Angularでフォームを実装する手段の一つです。
フォームの実装手段としては、もう一つ「リアクティブフォーム」という方法がありますが、今回はそちらにはあまり触れません。(またどこかで整理したいと思います。)
今回はテンプレート駆動フォームでのフォームの実装方法について整理していこうと思います。
作成するサンプルページ
実装済みのソースコードは以下ですので参考にしていただければと思います。
https://github.com/Nkot117/sample-NgForm
準備
FormsModuleの導入
テンプレート駆動フォームで必要になるFormsModuleの導入します。
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms'; //追加
import { AppComponent } from './app.component';
import { UserFormComponent } from './user-form/user-form.component';
@NgModule({
declarations: [AppComponent, UserFormComponent],
imports: [BrowserModule, FormsModule], // FormsModuleを追加
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
テンプレートの準備
サンプルページのテンプレートを作成します。
ngFormを使用したフォームの実装は後々の手順でやるので、ここでは一旦シンプルなフォームのみ作成します。
<div class="container">
<h1>ユーザー情報入力フォーム</h1>
<form>
<div class="form-group">
<label for="name">名前</label>
<input name="name" type="text" class="form-control" id="name" required minlength="2" />
</div>
<div class="form-group">
<label for="email">メールアドレス</label>
<input name="email" type="email" class="form-control" id="email" required pattern="^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$"/>
</div>
<button type="submit" class="btn btn-success">送信する</button>
</form>
</div>
以上で準備はOKです。次から色々実装していこうと思います。
フォームに入力した内容を送信する
フォームに入力した内容を取得し、送信できるようにしていこうと思います。
まずはformタグにて、
①ngFormディレクティブをテンプレート変数に代入
②「送信する」ボタンを押下した際に実行する関数の設定を行います。
<div class="container">
<h1>ユーザー情報入力フォーム</h1>
<form #userForm="ngForm" (ngSubmit)="submit(userForm)"> // ここを編集
<div class="form-group">
<label for="name">名前</label>
<input name="name" type="text" class="form-control" id="name" required minlength="2" />
</div>
<div class="form-group">
<label for="email">メールアドレス</label>
<input name="email" type="email" class="form-control" id="email" required pattern="^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$"/>
</div>
<button type="submit" class="btn btn-success">送信する</button>
</form>
</div>
#userForm="ngForm" で行なっているのが、①のngFormディレクティブをテンプレート変数に代入になります。
(ngSubmit)="submit(userForm)"で行っているのが②「送信する」ボタンを押下した際に実行する関数の設定を行います。
「送信する」ボタンをタップした際には、コンポーネント側で定義するsubmit関数をngFormディレクティブをテンプレート変数のuserFormを引数に設定して実行するように設定しています。
あとは、各inputタグの入力値を双方向でバインドするように設定します。
<div class="container">
<h1>ユーザー情報入力フォーム</h1>
<form #userForm="ngForm" (ngSubmit)="submit(userForm)">
<div class="form-group">
<label for="name">名前</label>
<input [(ngModel)]="user.name" name="name" type="text" class="form-control" id="name" required minlength="2" /> // ここを編集
</div>
<div class="form-group">
<label for="email">メールアドレス</label>
<input [(ngModel)]="user.email" name="email" type="email" class="form-control" id="email" required pattern="^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$"/> // ここを編集
</div>
<button type="submit" class="btn btn-success">送信する</button>
</form>
</div>
以上でテンプレート側の実装は完了です。
あとはロジック側に「送信する」ボタンタップ時に実行されるsubmit関数を定義してみます。
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { User } from '../user';
@Component({
selector: 'app-user-form',
templateUrl: './user-form.component.html',
styleUrls: ['./user-form.component.scss']
})
export class UserFormComponent implements OnInit {
public user: User = new User("","")
public showErrorMessage: boolean = false;
constructor() {}
ngOnInit(): void {
console.log('UserFormComponent@ngOnInit');
}
public submit(form: NgForm): void{
alert(`名前:${form.value}\nメールアドレス:${form.value}`)
}
}
上記のsubmit関数が「送信する」ボタンタップ時に実行されます。
テンプレート側の入力値はform.value.(inputタグのname属性に設定した名前)で取得することができます。
今回はどこかへの送信は行いませんが、入力値が取得できているか確認できるようにalertで確認できるようにしています。
実行するとこんな感じで入力値がコンポーネント側で取得できていることがわかります。
まとめ
Angularでフォームを実装する手段の一つであるテンプレート駆動フォームを実装してみました。
記事では整理できていませんが、バリデーションチェックも簡単に実装できます。(サンプルコードは少し実装しているので、気になったら確認してもらえると嬉しいです。)
「リアクティブフォーム」についてもどこかで整理したいなと思っています。