【Angular】テキストボックスが空の場合にエラーメッセージを表示する

💡この記事は2年以上前に執筆しました。Angular v6.1.10時点の実装を紹介しています。
テキストボックスに文字が入力されていない場合、すぐ下に「値が入力されていません」のエラーメッセージを表示する機能を作ります。
Angularが用意した機能として、データバインディングというものがあります。
import { Component } from "@angular/core";
@Component({
selector: "app-databinding",
template: <span>ようこそ、{{ userName }}さん!</span>
})
export class DataBindingComponent {
userName = "太郎";
}

TypeScriptセクション(以下、ts)で定義した変数を、テンプレート側(html)で参照できる機能です。
今回はデータバインディングではなく、テンプレート参照変数を使います。
テンプレート参照変数
Angularで作成したプロジェクトでは、HTMLセクションのことを「テンプレート」と呼びます。
AngularのHTMLテンプレートはAngularが用意した特別な構文を使用することで、条件分岐(if)・ループ(for)・変数定義などが実装できます。
これにより、アプリケーションのHTML表現を拡張できるというわけです。
今回取り上げるテンプレート参照変数は、すべてテンプレートの中で完結します。
テンプレート構文の中で変数を定義、変数に値を格納、変数の値を参照できるのです。
テンプレート参照変数はテンプレート内の要素に#変数名
を定義することで使用できます。
import { Component } from "@angular/core";
@Component({
selector: "app-template-reference-variables",
template: `
<input #var1 type="text" [(ngModel)]="inputText" />
<span>Value: {{ var1.value }}</span>
`})
export class TemplateReferenceVariablesComponent {
inputText = "";
}

これを踏まえて、テキストボックスが空の場合にエラーメッセージを表示させる実装をします。
import { Component } from "@angular/core";
@Component({
selector: "app-required-text-box",
template: `
<input type="text" [(ngModel)]="inputText" #var1="ngModel" required />
<div *ngIf="var1.errors?.['required']">値を入力して下さい。</div>
`
})
export class RequiredTextBoxComponent {
inputText = "";
}

Angular公式に以下の説明があります。
変数が#var="ngModel"のように右側に名前を指定すると、変数は要素において一致するexportAs名をもつディレクティブやコンポーネントを参照します。
※旧リンク(Angularがテンプレート変数に値を割り当てる方法) より引用
テンプレート参照変数について記載されている現在のページは以下です。
これを利用して、#var1="ngModel"
で定義と、テンプレート参照変数へのngModel
の割り当てを行います。
またngIf="var1.errors?.['required']
で参照しています。
テキストボックス(<input type="text">
)を必須項目required
にしておきます。
<div *ngIf="var1.errors?.['required']">
ここでテキストボックスのエラーを検知します。この*ngIf
の条件が満たされれば、エラーメッセージを表示する仕組みです。
このように<input>
要素の値を表示したい場合にはテンプレート参照変数を、ts側で値を加工する場合はデータバインディングを使用するなど、状況に応じて使い分けています。
注意
テンプレート参照変数は読み取り専用です。
[(ngModel)]="piyopiyo"
とすることはできません
またテンプレート参照変数の命名ですが、"-"を使うと
Template parse errors: "-" is not allowed in reference names
こんな感じで怒られました。ハイフンは使用できないようです。
"_"(アンダーバー)は使えました。
また<input>
要素でngModel
を使う場合は、FormsModule
のインポートが必要となります。忘れずapp.module.tsに記載してください。
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { AppComponent } from "./app.component";
@NgModule({
declarations: [
AppComponent,
],
imports: [BrowserModule, FormsModule],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule {}
おわりに

いつもこの本にお世話になってるんですが、慣れない言葉の連続で頭に入ってきません🐑💤💭
Angular公式はきっと賢い人が作ったのでしょう。それっぽい検索ワードで調べたのにわたしにもわかる解説が出てきませんでした。
素人は『 テンプレート駆動フォーム 』なんて専門用語わからないです。公式さんにはもっと初心者に優しくなってほしいものです。
<参考記事>
- テンプレート構文
- テンプレート駆動フォーム
- テンプレート変数
- この記事を共有する