開発覚書はてな版

個人的な開発関連の備忘録

【Angular】ngModel に拡張メソッドを実装する

概要

Angular の ngModel 使用時にHTML側で頻繁に touched or dirty の判定を使用するケースがあります。 面倒なので拡張メソッド化してみたいと思います。

基本的には以下の記事と同様に拡張できます。

kakkoyakakko2.hatenablog.com

実行環境

  • Node.js 10.9.x

使用ライブラリ

  • Angular 7.1.x

実装方針

  • 基本的な拡張メソッドの実装と同様に NgModel に拡張メソッドを追加する。
  • touchedOrDirty 拡張メソッドを追加して、NgModel.touched || NgModel.dirty の結果を戻す。

サンプルソース

ng-model.extension.ts
export {};

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

declare module '@angular/forms/src/directives/ng_model' {

  interface NgModel {
    /**
     * NgModel.touched or dirty
     * @returns touched or dirty
     */
    touchedOrDirty(): boolean;
  }
}

NgModel.prototype.touchedOrDirty = function() {
  const control = this as NgModel;
  return control.touched || control.dirty;
};
app.component.html
<div>
  <form #form1="ngForm">
    <input type="text" name="memo" required [(ngModel)]="text1" #txt1="ngModel">
    <ul>
      <li *ngIf="form1.valid">form.valid</li>
      <li *ngIf="form1.invalid">form.invalid</li>
      <li *ngIf="form1.touched">form.touched</li>
      <li *ngIf="form1.untouched">form.untouched</li>
      <li *ngIf="form1.pristine">form.pristine</li>
      <li *ngIf="form1.dirty">form.dirty</li>
      <li>txt1.touchedOrDirty {{ txt1.touchedOrDirty() ? 'true' : 'false' }}</li>
    </ul>
  </form>
</div>
app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  text1 = '';
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import './ng-model.extension';

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

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

サンプルソース一式

github.com