こんにちは。アーティサン株式会社の木戸です。
本記事では Angular で属性ディレクティブを用いた、整数のみの入力フォーム作成手法をご紹介します。
Angular で年齢等、整数のみの入力フォームを作成したい、という方に向けた記事です。
Angular で整数のみの入力フォームを実現する場合、関数を作成しinput 要素のイベントに紐付ける、もしくは、属性ディレクティブを作成しinput 要素の属性として記述するという 2 つの手法があります。
- 関数を作成しinput 要素のイベントに紐付ける
関数を作成しinput 要素のイベントに紐付ける手法では、利用する各コンポーネント毎に、関数のインポートとメンバ変数への代入が必要になり、余計なメンバ変数の作成やソースコードが煩雑になります。
- 属性ディレクティブを作成しinput 要素の属性として記述
これに対して、属性ディレクティブを用いた手法ならば、属性ディレクティブを作成後、input 要素の属性として宣言的な記述のみで利用できるため、余計なメンバ変数の代入がなくソースコードもスッキリさせる事ができます。
属性ディレクティブとは
属性ディレクティブとは、HTML 要素に属性として記述する事によって、DOM 要素と Angular コンポーネントの外観や動作を変更できるクラスです。
環境
- Angular: 12.0.3
- Angular CLI: 12.0.3
- TypeScript: 4.2.3
実装方針
- 属性ディレクティブの作成
- 属性ディレクティブに、input イベントを受け取る関数を追加
- input 要素に属性ディレクティブを追加
実装
$ ng generate directive integerOnly
属性ディレクティブに、input イベントを受け取る関数を追加(.ts)
input イベントを受け取る関数を追加し、整数以外の入力値を削除する(10-13 行)
// integer-only.directive.ts
import { Directive, ElementRef, HostListener } from "@angular/core";
@Directive({
selector: "[appIntegerOnly]",
})
export class IntegerOnlyDirective {
constructor(private elemRef: ElementRef<HTMLInputElement>) {}
@HostListener("input") onInput(): void {
const initialValue = this.elemRef.nativeElement.value;
this.elemRef.nativeElement.value = initialValue.replace(/[^0-9]*/g, "");
}
}
input 要素に属性ディレクティブを追加(.html)
input 要素に属性ディレクティブを追加
<input type="text" appIntegerOnly />
関数をイベントに紐付ける手法と、属性ディレクティブを用いた手法の比較
ここで、関数をイベントに紐付ける手法と、属性ディレクティブを用いた手法のコードを比較してみましょう。
関数をイベントに紐付ける手法と比べ、属性ディレクティブを用いた手法では余計なメンバ変数の代入がなく、かつ宣言的に記述できるためコードがスッキリします。
関数をイベントに紐付ける場合
- 入力値を整数のみにする関数を import
- import した関数をメンバ変数に代入
- input 要素の(input)イベントに関数を代入
import { Component } from "@angular/core";
import { onInput } from "./number-only";
@Component({
selector: "app-integer-directive",
templateUrl: "./integer-directive.component.html",
styleUrls: ["./integer-directive.component.scss"],
})
export class IntegerDirectiveComponent {
public onInput = onInput;
}
<input (input)="onInput($event)" type="text" />
属性ディレクティブを用いた場合
属性ディレクティブを作成し、input 要素に属性を追加
<input type="text" appIntegerOnly />
あとがき
本記事では、属性ディレクティブを用いて整数のみの入力フォームを作成しました。
なお、属性ディレクティブにメンバ変数を追加し、input 要素から属性を通して値を渡す事によって動作をカスタマイズする事も可能です。
関連リンク
木戸裕貴
私は主にTypeScriptでのフロントエンド開発を担当しております。