iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
Modern Web

angular專案開發指南系列 第 15 篇

Angular 表單驗證

  • 分享至 

  • xImage
  •  

前言

驗證使用者輸入的準確性和完整性,可提高資料品質。該頁面顯示瞭如何從 UI 驗證使用者輸入,Angular 提供 範本驅動表單中驗證 與 響應式表單中驗證 一般來說,結構簡單的表單我會使用 範本驅動表單中驗證 方式,複雜的大型表單我會使用 響應式表單中驗證。
以下示範如何在 範本驅動表單 和 響應式表單 中進行驗證並顯示有用的驗證訊息。


實作範本驅動表單

First Name 加入驗證 src\app\tenant\tenant.component.html

<div>
    <label>First Name   </label>

    <!-- 檢查 minlength="3" 與 required -->
    <input type="text" nbInput [(ngModel)]="addTenant.fname" #fname="ngModel" minlength="3" required />
</div>
<div *ngIf="fname.invalid && (fname.dirty || fname.touched)" class="alert">
    <span *ngIf="fname.errors?.['required']">此欄位必填</span>
    <span *ngIf="fname.errors?.['minlength']">至少輸入 3 個字</span>
</div>

驗證項目

  1. 此欄位必填
  2. 至少輸入 3 個字

美化驗證樣式 src\app\tenant\tenant.component.scss

nb-card-body {
    div {
        ...

        // 驗證欄位
        &.alert {
            margin: 0;
            color: red;
        }
    }

    // 錯誤訊息
    span {
        display: inline-block;
        width: 100%;
        text-align: center;
    }
}

範本驅動表單驗證結果

g8

範例解釋

  1. #fname="ngModel" NgModel 匯出一個名叫 fname 的區域性變數。NgModel 把自己控制的 FormControl 實例的屬性映射出去,讓你能在範本中檢查控制元件的狀態。

  2. *ngIf="fname.invalid && (fname.dirty || fname.touched)" 檢查控制元件的 dirty 狀態或 touched 狀態,避免一開始還沒操作的情況下就被驗證為錯誤輸入。

    • 當用戶在被監視的欄位中修改該值時,控制元件就會被標記為 dirty
    • 當用戶的表單控制元件失去焦點時,該控制元件就會被標記為 touched

打開 console 檢視元素會發現 Angular 有幫你加入 ng-dirty ng-invalid ng-touched 的樣式名。

<input type="text" nbinput="" minlength="3" required="" class="size-medium status-basic shape-rectangle nb-transition ng-dirty ng-invalid ng-touched">

響應式表單

要使用響應式表單需要載入 ReactiveFormsModule 模組

src\app\app.module.ts

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

imports: [
    FormsModule,
    ReactiveFormsModule,
    ...
]

加入 formGroup 到 src\app\tenant\tenant.component.html

<form [formGroup]="helloForm">
    ...
    <div>
        <label>Last Name   </label>
        <input type="text" nbInput class="form-control" formControlName="lname" required />
    </div>
    <div *ngIf="lname.invalid && (lname.dirty || lname.touched)" class="alert">
        <span *ngIf="lname.errors?.['required']">此欄位必填</span>
        <span *ngIf="lname.errors?.['minlength']">至少輸入 3 個字</span>
    </div>
    ...
</form>

載入模組 src\app\tenant\tenant.component.ts

import { FormControl, FormGroup, Validators, FormBuilder } from '@angular/forms';

...

helloForm: any;

editItem(dialog: TemplateRef<any>, idx: number) {
    // 被選擇項目資料寫入對話框
    this.addTenant.fname = targetObj.first_name;
    this.addTenant.lname = targetObj.last_name;
    this.addTenant.phone = targetObj.phone;
    this.addTenant.address = targetObj.address;

    ...
}

get lname() {
    return this.helloForm.get('lname');
}

async ngOnInit(): Promise<void> {
    ...

    this.helloForm = new FormGroup({
        lname: new FormControl(
            this.addTenant.lname,
            [Validators.required,Validators.minLength(3)
        ]),
    });
}

這些驗證器都是同步的,所以它們作為第二個引數傳遞。注意,你可以透過把這些函式放到一個數組中傳入來支援多個驗證器。

響應式表單驗證結果

g9


結論

編輯租戶表單原本就使用了雙向綁定特性,因此比較適用 範本驅動表單中驗證 的方式,但是為求完整展示範例,在 First name 是使用 範本驅動表單 中驗證,而在 Last name 是使用 響應式表單驗證。

租戶管理元件功能都做好了,下一篇回到 Angular 基本概念整理跟大家分享一下生命週期鉤子。


參考

Validating form input


上一篇
實作租戶管理頁面(2)
下一篇
Angular 元件的生命週期
系列文
angular專案開發指南 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言