Reactive Forms 表單驗證
添加驗證器
在 Reactive Forms 中,我們可以在建立 FormControl 時加入驗證器。有兩種方式可以添加驗證器:
方式一:直接傳入驗證器陣列
loginForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required, Validators.minLength(6)])
});
方式二:使用 configuration object
loginForm = new FormGroup({
email: new FormControl('', {
validators: [Validators.required, Validators.email],
}),
password: new FormControl('', {
validators: [Validators.required, Validators.minLength(6)],
// 也可以加入非同步驗證器
// asyncValidators: [...]
}),
});
常用內建驗證器
Angular 提供多種內建驗證器:
Validators.required
- 必填欄位Validators.email
- 必須是有效的電子郵件格式Validators.minLength(n)
- 最小長度Validators.maxLength(n)
- 最大長度Validators.pattern(regex)
- 符合指定的正則表達式模式Validators.min(n)
- 最小數值(用於數字輸入)Validators.max(n)
- 最大數值(用於數字輸入)
在範本中檢查驗證狀態
我們可以在範本中檢查控制項的狀態,以顯示適當的錯誤訊息:
@if(loginForm.controls.email.touched && loginForm.controls.email.dirty &&
loginForm.controls.email.invalid){
<p class="control-error">Please enter a valid email address.</p>
}
這種寫法雖然直接,但過於冗長。我們可以在元件類別中使用 getter 方法來簡化:
get emailIsInvalid() {
return (
this.loginForm.controls.email.touched &&
this.loginForm.controls.email.dirty &&
this.loginForm.controls.email.invalid
);
}
get passwordIsInvalid() {
return (
this.loginForm.controls.password.touched &&
this.loginForm.controls.password.dirty &&
this.loginForm.controls.password.invalid
);
}
然後在範本中簡化使用:
@if(emailIsInvalid){
<p class="control-error">Please enter a valid email address.</p>
}
@if(passwordIsInvalid){
<p class="control-error">Password must be at least 6 characters.</p>
}
檢查特定類型的錯誤
通常,我們需要針對不同類型的錯誤顯示不同的訊息。可以使用 errors
屬性來檢查特定類型的錯誤:
@if(loginForm.controls.email.touched && loginForm.controls.email.invalid){
@if(loginForm.controls.email.errors?.['required']){
<p class="control-error">Email is required.</p>
} @else if(loginForm.controls.email.errors?.['email']){
<p class="control-error">Please enter a valid email format.</p>
}
}
同樣,我們可以通過 getter 方法使這個過程更簡潔:
get emailErrors() {
const control = this.loginForm.controls.email;
if (control.touched && control.invalid) {
if (control.errors?.['required']) return 'Email is required.';
if (control.errors?.['email']) return 'Please enter a valid email format.';
}
return null;
}
範本中使用:
@if(emailErrors){
<p class="control-error">{{ emailErrors }}</p>
}
表單整體驗證
除了檢查個別控制項外,我們也可以檢查整個表單的有效性:
<button type="submit" [disabled]="loginForm.invalid">Login</button>
這會在表單無效時禁用提交按鈕。
驗證狀態的 CSS 類別
和 Template-driven Forms 類似,Angular 也會為 Reactive Forms 的控制項添加以下 CSS 類別:
ng-valid
/ng-invalid
ng-touched
/ng-untouched
ng-dirty
/ng-pristine
可以利用這些類別來設置樣式:
input.ng-invalid.ng-touched {
border: 1px solid red;
}
input.ng-valid.ng-touched {
border: 1px solid green;
}
表單驗證的最佳實踐
使用 getter 方法:簡化範本中的驗證邏輯
具體的錯誤訊息:針對不同類型的錯誤提供明確的訊息
禁用提交按鈕:在表單無效時禁用提交按鈕,避免無效提交
CSS 狀態樣式:提供視覺反饋,讓使用者知道輸入的狀態
考慮使用 FormBuilder:使用 FormBuilder 可以簡化表單建立過程
Last updated