強大的 Angular 表單驗證功能詳細介紹,angular詳細介紹
Angular 支援非常強大的內建表單驗證,maxlength、minlength、required 以及 pattern。使用 Angular 的內建表單校正能夠完成絕大多數的業務情境的校正需求,但有時我們還需要實現更為複雜的表單校正功能,這時可以使用 Angular 提供的表單自訂校正(Custom Validator)。下面,我們就來瞭解一下如何使用 Angular 的自訂表格單校正
:
1、首先,來建立我們的註冊組件(register),並在模版中顯示一個簡單的表單
<h3 class="text-center">註冊</h3><form> <div class="form-group"> <label for="username">使用者名稱:</label> <input type="text" id="username" class="form-control" > </div></form>
為了使表單看上去能夠漂亮一些,在 index.html 中引入 bootstrap 樣式檔案:
複製代碼 代碼如下:
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
2、接下來確定我們的驗證需求:
我們希望使用者名稱只能包含數字、字母和底線,且不能以底線開頭
首先為 form 標籤添加 formGroup 指令:
<form [formGroup]="registerForm" >
並且為 input 標籤添加 formControlName 指令:
複製代碼 代碼如下:
<input formControlName="username" type="text" id="username" class="form-control" >
3、在代碼中定義驗證規則:
從內建表單模組中匯入以下類:
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
其中:
1. formBuilder 用來構建表單資料
2. formGroup 表示表單類型
3. Validators 包含了表單內建的驗證規則,如: Validators.required
定義表單屬性
registerForm: FormGroup;
定義表單驗證不通過時每一項顯示的錯誤訊息(目前我們只有 username )
formErrors = { username: '' };
為每一項驗證規則定義驗證失敗時的解說文字(表單控制項可能有多條驗證規則,由不通過的驗證說明構成一條錯誤訊息)
validationMessage = { 'username': { 'minlength': '使用者名稱長度最少為3個字元', 'maxlength': '使用者名稱長度最多為10個字元', 'required': '請填寫使用者名稱' } };
在建構函式中添加 fb 屬性用來構建表單
constructor(private fb: FormBuilder) { }
添加構建表單的方法
buildForm(): void { // 通過 formBuilder構建表單 this.registerForm = this.fb.group({ /* 為 username 添加3項驗證規則: * 1.必填, 2.最大長度為10, 3.最小長度為3 * 其中第一個Null 字元串參數為表單的預設值 */ 'username': [ '', [ Validators.required, Validators.maxLength(10), Validators.minLength(3) ]] });
接下來我們添加一個方法用來更新錯誤資訊
onValueChanged(data?: any) { // 如果表單不存在則返回 if (!this.registerForm) return; // 擷取當前的表單 const form = this.registerForm; // 遍曆錯誤訊息對象 for (const field in this.formErrors) { // 清空當前的錯誤訊息 this.formErrors[field] = ''; // 擷取當前表單的控制項 const control = form.get(field); // 當前表單存在此空間控制項 && 此控制項沒有被修改 && 此控制項驗證不通過 if (control && control.dirty && !control.valid) { // 擷取驗證不通過的控制項名,為了擷取更詳細的不通過資訊 const messages = this.validationMessage[field]; // 遍曆當前控制項的錯誤對象,擷取到驗證不通過的屬性 for (const key in control.errors) { // 把所有驗證不通過項的解說文字拼接成錯誤訊息 this.formErrors[field] += messages[key] + '\n'; } } } }
下面只需要在表單構建結束後初始化錯誤訊息,並且在每次表單資料更改時更新錯誤訊息就可以了
在 buildForm 方法中添加如下代碼
// 每次表單資料發生變化的時候更新錯誤資訊 this.registerForm.valueChanges .subscribe(data => this.onValueChanged(data)); // 初始化錯誤資訊 this.onValueChanged();
此時,我們已經很好的控制了錯誤資訊,下面只需要在表單模版中添加錯誤資訊的顯示就可以了
在 input 標籤下方添加如下代碼:
<div *ngIf="formErrors.username" class="showerr alert alert-danger" >{{ formErrors.username }}</div>
添加如下代碼到表單模版的 css 中:
form { width: 90%; max-width: 45em; margin: auto; } .showerr { white-space: pre-wrap; }
現在我們就可以嘗試運行了,在代碼不報錯的情況下已經能夠看到非常好的效果了
如果代碼報錯或沒有出現想象中的效果則可以參照本文結尾的完整代碼進行修改
4、雖然我們已經搭建了整個布局,但是還沒有實現我們的最終目的:實現自訂的表單驗證
接下來我們建立一個正則驗證器,建立檔案 validate-register.ts :
import { ValidatorFn, AbstractControl } from '@angular/forms'; export function validateRex(type: string, validateRex: RegExp): ValidatorFn { return (control: AbstractControl): {[key: string]: any} => { // 擷取當前控制項的內容 const str = control.value; // 設定我們自訂的驗證類型 const res = {}; res[type] = {str} // 如果驗證通過則返回 null 否則返回一個對象(包含我們自訂的屬性) return validateRex.test(str) ? null : res; } }
下面我們在代碼中匯入此函數:
import { validateRex } from './validate-register';
修改 validationMessage 屬性為:
// 為每一項表單驗證添加解說文字 validationMessage = { 'username': { 'minlength': '使用者名稱長度最少為3個字元', 'maxlength': '使用者名稱長度最多為10個字元', 'required': '請填寫使用者名稱', 'notdown': '使用者名稱不能以底線開頭', 'only': '使用者名稱只能包含數字、字母、底線' } };
修改 buildForm 方法:
// 通過 formBuilder構建表單 this.registerForm = this.fb.group({ /* 為 username 添加 5 項驗證規則: * 1.必填, 2.最大長度為10, 3.最小長度為3, 4.不能以底線開頭, 5.只能包含數字、字母、底線 * 其中第一個Null 字元串參數為表單的預設值 */ 'username': [ '', [ Validators.required, Validators.maxLength(10), Validators.minLength(3), validateRex('notdown', /^(?!_)/), validateRex('only', /^[1-9a-zA-Z_]+$/) ]] });
OK ! 大功告成了,趕緊運行代碼嘗試一下吧,我們可以隨時添加各種驗證規則,只需要修改 validationMessage 屬性和 buildForm 方法即可!
如果添加多個表單控制項的話還需要修改 formErrors,例如添加 password 控制項則修改 formErrors 為
formErrors = { username: '', password: ''};
大家可自行嘗試一下!
完整代碼:
register.component.html
<h3 class="text-center">註冊</h3> <form [formGroup]="registerForm" > <div class="form-group"> <label for="username">使用者名稱:</label> <input formControlName="username" type="text" id="username" #username class="form-control" > <div *ngIf="formErrors.username" class="showerr alert alert-danger" >{{ formErrors.username }}</div> </div> </form>
register.component.css:
form { width: 90%; max-width: 45em; margin: auto; } .showerr { white-space: pre-wrap; }
register.component.ts:
import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; import { validateRex } from './validate-register'; @Component({ selector: 'app-register', templateUrl: './register.component.html', styleUrls: ['./register.component.css'] }) export class RegisterComponent implements OnInit { // 定義表單 registerForm: FormGroup; // 表單驗證不通過時顯示的錯誤訊息 formErrors = { username: '' }; // 為每一項表單驗證添加解說文字 validationMessage = { 'username': { 'minlength': '使用者名稱長度最少為3個字元', 'maxlength': '使用者名稱長度最多為10個字元', 'required': '請填寫使用者名稱', 'notdown': '使用者名稱不能以底線開頭', 'only': '使用者名稱只能包含數字、字母、底線' } }; // 添加 fb 屬性,用來建立表單 constructor(private fb: FormBuilder) { } ngOnInit() { // 初始化時構建表單 this.buildForm(); } // 構建表單方法 buildForm(): void { // 通過 formBuilder構建表單 this.registerForm = this.fb.group({ /* 為 username 添加3項驗證規則: * 1.必填, 2.最大長度為10, 3.最小長度為3, 4.不能以底線開頭, 5.只能包含數字、字母、底線 * 其中第一個Null 字元串參數為表單的預設值 */ 'username': [ '', [ Validators.required, Validators.maxLength(10), Validators.minLength(3), validateRex('notdown', /^(?!_)/), validateRex('only', /^[1-9a-zA-Z_]+$/) ]] }); // 每次表單資料發生變化的時候更新錯誤資訊 this.registerForm.valueChanges .subscribe(data => this.onValueChanged(data)); // 初始化錯誤資訊 this.onValueChanged(); } // 每次資料發生改變時觸發此方法 onValueChanged(data?: any) { // 如果表單不存在則返回 if (!this.registerForm) return; // 擷取當前的表單 const form = this.registerForm; // 遍曆錯誤訊息對象 for (const field in this.formErrors) { // 清空當前的錯誤訊息 this.formErrors[field] = ''; // 擷取當前表單的控制項 const control = form.get(field); // 當前表單存在此空間控制項 && 此控制項沒有被修改 && 此控制項驗證不通過 if (control && control.dirty && !control.valid) { // 擷取驗證不通過的控制項名,為了擷取更詳細的不通過資訊 const messages = this.validationMessage[field]; // 遍曆當前控制項的錯誤對象,擷取到驗證不通過的屬性 for (const key in control.errors) { // 把所有驗證不通過項的解說文字拼接成錯誤訊息 this.formErrors[field] += messages[key] + '\n'; } } } } }
validate-register.ts:
import { ValidatorFn, AbstractControl } from '@angular/forms'; export function validateRex(type: string, validateRex: RegExp): ValidatorFn { return (control: AbstractControl): {[key: string]: any} => { // 擷取當前控制項的內容 const str = control.value; // 設定我們自訂的嚴重類型 const res = {}; res[type] = {str} // 如果驗證通過則返回 null 否則返回一個對象(包含我們自訂的屬性) return validateRex.test(str) ? null : res; } }
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。