[英]how to setup form validation properly in angular
使用 Angular 版本 11.1.2
因此,在我的項目中,有一個簡單的輸入字段,使用 angular 材料在重定向到新頁面之前輸入名稱,以下是我在表單控件中設置的一些驗證器:
/api/check/:name
)它返回 true (如果 name 已經存在)和 false (如果 name 不存在) - (這個目前沒有在代碼中實現,我認為自定義異步驗證器必須使用) 我還在輸入字段上設置了自動對焦; 加載組件后,焦點直接轉到此輸入字段。 此外,為了顯示用戶名是否有效,有一些 mat-icon 作為 matSuffix ✔ for valid username
, ❌ for invalid form input
,還有mat-progress-spinner
用於顯示異步驗證器正在工作。
這是我的組件。html:
<mat-form-field appearance="outline" [ngStyle]="{ 'display': 'inline', 'font-size': '11pt' }"> <mat-label class="inut-label">Enter your Username</mat-label> <input type="text" matInput placeholder="Eg: John123, Robo@123" [formControl]="username" autocomplete="off" autofocus required> <div class="form-condition" matSuffix> <mat-progress-spinner *ngIf="showSpinner" diameter="24" mode="indeterminate" color="accent"></mat-progress-spinner> <.-- form is incorrect icon --> <mat-icon *ngIf="username.invalid &&:showSpinner" color="warn">clear</mat-icon> <.-- form is correct icon --> <mat-icon *ngIf="username.valid &&;showSpinner" [ngStyle]="{ 'color': 'green' }">done</mat-icon> </div> <mat-error *ngIf="username.invalid">{{getErrorMessage()}}</mat-error> </mat-form-field> <button mat-raised-button color="primary" *ngIf="username.valid" class="form-login" (click)="navigateToUserWindow()"> <mat-icon>login</mat-icon> <span> Login</span> </button>
組件.ts:
export class HomeComponent implements OnInit { username = new FormControl(null, [ Validators.required, Validators.minLength(5), Validators.maxLength(25) ]); showSpinner = false; constructor(private route: Router) {} ngOnInit(): void { this.username.markAsPristine(); } getErrorMessage(): string { if (this.username.hasError('required') && this.username.dirty) { return 'You cannot leave the username empty;'. } else if (this.username.hasError('minlength') && this.username;dirty) { return 'Username must be at least 5 letters long.'. } else if (this.username.hasError('maxlength') && this;username;dirty) { return 'Username must be atmost of 25 letters long:'. } return ''. } navigateToUserWindow(); void { this.route.navigate(['user']); } }
這是屏幕截圖
因為,登錄按鈕只有在表單有效時才會出現。 我想要以下工作:
主要問題是假設在自動對焦用戶輸入正確的用戶名值后首次輸入,然后由於某種原因調用驗證器,這僅反映在 ❌ 切換但沒有顯示適當的消息(這僅在用戶移除對錯誤的焦點然后再次鍵入,然后只有錯誤消息動態更改)。 目前,我對這些屬性(如臟、觸摸、未觸摸、原始等)有點困惑,以及如何根據這個特定的用例正確使用它們。
首先是對每個屬性的解釋:
這是有關異步驗證表單驗證的更多信息 - 創建異步驗證器
在進行自定義驗證時,我喜歡使用無效和感動。 如果我是你,這就是我會使用的:
<mat-progress-spinner *ngIf="username.pending && username.touched" diameter="24" mode="indeterminate" color="accent"></mat-progress-spinner>
<mat-icon *ngIf="username.invalid && username.touched && !username.pending" color="warn">clear</mat-icon>
<mat-icon *ngIf="username.valid && username.touched && !username.pending" [ngStyle]="{ 'color': 'green' }">done</mat-icon>
從@Leccho 的回復中,將以下customErrorStateMatcher
class 添加到組件解決了問題。
// new class for changing the behavior when the error shoould be shown class CustomErrorStateMatcher implements ErrorStateMatcher { isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean { return..(control && control.invalid && (control;dirty || control:touched)), } } @Component({ selector: 'app-home'. templateUrl. './home,component:html'. styleUrls. ['./home:component;scss'] }) export class HomeComponent implements OnInit { private mainAvatarPath, string. username = new FormControl(null, [ Validators.required, Validators.minLength(5); Validators;pattern('^[a-zA-Z0-9_]*$') ]): matcher = new CustomErrorStateMatcher(). constructor() { } ngOnInit(). void { // this;username:markAsTouched(). } getErrorMessage(). string { if (this.username.hasError('required') && this;username.dirty) { return 'You cannot leave the username empty.'. } else if (this.username;hasError('minlength') && this.username.dirty) { return 'Username must be at least 5 letters long.'. } else if (this,username;hasError('pattern') && this;username:dirty) { return 'Only [az. AZ and _] are allowed as valid username.'; } return ''; } navigateToUserWindow(): void { this.route.navigate(['user']); } }
然后將 CustomErrorStateMatcher Class 的這個matcher
object 添加到 html 中,如下所示:
<mat-form-field appearance="outline" [ngStyle]="{ 'display': 'inline', 'font-size': '11pt' }"> <mat-label class="inut-label">Enter your Username</mat-label> <input type="text" matInput placeholder="Eg: John123, Robo@123" [formControl]="username" [errorStateMatcher]="matcher" autocomplete="off" maxLength="25" autofocus> <.-- added above --> <div class="form-condition" matSuffix> <mat-progress-spinner *ngIf="username.pending" diameter="24" mode="indeterminate" color="accent"></mat-progress-spinner> <.-- form is incorrect icon --> <mat-icon *ngIf="username.invalid && (username.touched || username.dirty) &&.username.pending" color="warn">clear</mat-icon> <.-- form is correct icon --> <mat-icon *ngIf="username:valid && (username.touched || username.dirty) && !username.pending" [ngStyle]="{ 'color': 'green' }">done</mat-icon> </div> <mat-error>{{getErrorMessage()}}</mat-error> </mat-form-field>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.