首頁  >  文章  >  web前端  >  深入了解Angular中的表單

深入了解Angular中的表單

青灯夜游
青灯夜游轉載
2021-04-27 09:43:572658瀏覽

本篇文章給大家詳細介紹一下Angular中的表單。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

深入了解Angular中的表單

Angular 表單


#什麼是範本式表單

表單的資料模型是透過元件範本中的相關指令來定義的, 因為使用這種方式定義表單的資料模型時, 我們會受限於HTML 的語法, 所以範本驅動方式只適合用於一些簡單的場景。

什麼是響應式表單

響應式表單提供了一種模型驅動的方式來處理表單輸入, 其中的值會隨時間而變化。使用響應式表單時, 透過編寫 TypeScript 程式碼而不是 HTML 程式碼來建立一個底層的資料模型, 在這個模型定義好以後, 使用一些特定的指令, 將模板上的 HTML 元素與底層的資料模型連接在一起。
注意:

  • 資料模型並不是一個任意的對象, 它是一個由angular/forms 模組中的一些特定的類, 如FormControl, FormGroup, FormArray 等組成的。在範本式表單中, 是不能直接存取到這些類別的。 【相關推薦:《angular教學》】

  • 響應式表單並不會替你產生 HTML, 範本還是需要自己來寫。

  • 範本式表單中, 是不能存取資料模型的相關類別的, 只能拿到表單最終的資料; 在響應式表單中, 是可以存取資料模型相關的類, 但由於它們是不可引用的, 故不能在模板中進行操作, 只能在TypeScript 程式碼中進行操作。

響應式表單

深入了解Angular中的表單

#FormGroup

FormGroup既可以代表表單的一部分, 又可以代表整個表單, 它是多個FormControl 的集合。 FormGroup 將多個 FormControl 的值和狀態聚合在一起, 在表單校驗中, 如果FormGroup 中有一個 FormControl 是無效的, 那整個 FormGroup 都是無效的。

FormControl

FormControl 是構成表單的基本單位, 通常情況下用來代表一個input 元素, 但是也可以用來代表一個更複雜的元件, 如日曆, 下拉選擇框。 FormControl 保存與其關聯的 HTML 元素的目前值以及元素的校驗狀態, 還有元素是否已修改過等資訊。

FormArray

FormArray 與 FormGroup 類似, 但是它有長度屬性。一般來說, FormGroup 用來代表整個表單或表單欄位的一個固定子集; 而 FormArray 通常用來代表一個可以成長的欄位集合。

表單校驗

Angular 內建校驗器

Angular為我們提供了幾個內建校驗器,以下是比較常用的校驗器:

  • Validators.required - 表單控制項值非空
  • Validators.email - 表單控制項值的格式是email
  • # Validators.minLength() - 表單控制項值的最小長度
  • Validators.maxLength() - 表單控制項值的最大長度
  • Validators.pattern() - 表單控制項的值需符合pattern對應的模式(正規表示式)

自訂響應式表單校驗器

在實際的開發中, 為了滿足專案的需求, 我們需要自訂一些校驗器。一般情況下, 可以將校驗函數定義成如下形式:

xxxxValidator(control: AbstarctControl): {[key: string]: any} {    
      // TODO 编写校验规则   
      return null;  
 }

下面以常見的註冊頁面為例:

初始化表單

ngOnInit(): void {  
     this.formModel = this.fb.group({    
	username: ['', [Validators.required, Validators.minLength(6)]],    
	// 密码    
	passwordsGroup: this.fb.group({     
	       password: [''],  
	       passwordConfirm: [''] 
	       }, { validator: this.equalValidator }),    
        // 手机号    
        mobile: ['', this.moblieValidator]  });
 }

編寫校驗器

// 手机号码校验
moblieValidator(control: AbstractControl): any {  
   const reg = /^((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8}$/;  
   const valid = reg.test(control.value);  
   console.log('mobile的校验结果:', valid); 
   return valid ? null : { mobile: true };
}

// 密码校验
equalValidator(group: FormGroup): any {  
   const password = group.get('password') as FormControl;  
   const passwordConfirm = group.get('passwordConfirm') as FormControl;  
   const valid = password.value === passwordConfirm.value;  
   console.log('密码校验结果', valid);  
   return valid ? null : { equal: true };
}

Angular 非同步校驗器

Angular的表單API 也支援非同步校驗器, 非同步校驗器可以呼叫遠端的服務來檢查表單的欄位的值。非同步校驗器與普通校驗器類似, 也是一個方法, 唯一不同的是非同步校驗器返回的不是一個對象, 而是一個可觀測的流。

moblieAsyncValidator(control: AbstractControl): Observable<any> {  
   const reg = /^((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1}))+\d{8}$/;  
   const valid = reg.test(control.value);  
   console.log(&#39;mobile的校验结果:&#39;, valid); 
   return of(valid ? null : { mobile: true }); 
 }

Angular 狀態欄位

  • #toucheduntouched

#這兩個字段表示使用者是否曾造訪過字段, 也就是這個字段是否獲得焦點。一般用於表單錯誤提示訊息是否顯示。同時, 如果有任何一個欄位是 touched, 那整個表單的 touched 屬性就是 true; 只有所有欄位是 untouched 時, 整個表單的 untouched 屬性才是 true。

  • pristinedirty

如果一个字段的值从来没有改变过, 那么它的 pristine 就是 true, dirty 就是 false; 反之, 如果字段的值被修改过, 那么它的pristine 就是 false, dirty 就是 true。 同时, 如果任何一个字段是 dirty, 那么整个表单的 dirty 属性就是 true; 只有所有字段是 pristine 时, 整个表单的 pristine 属性才是 true。

  • pending

当一个字段处于异步校验时, 该字段的 pending 属性是 true。

自定义模板式表单的校验器

在深入了解Angular中的表單里, 我们后台有一个编码的数据模型, 只需要将校验器的方法挂在指定字段属性上就可以了。 但是, 在模板式表单里, 后台是没有这类数据模型的, 指令才是唯一能用的东西, 所以我们需要将校验方法包装成指令, 然后才能在模板中使用它。

编写指令

@Directive({  
   selector: &#39;[mobile]&#39;, 
    providers: [{provide: NG_VALIDATORS, useValue: moblieValidator, multi: true}]})
 export class MobileValidatorDirective {  
    constructor() { }
 }
 
// html中引用
<div>  手机号:<input ngModel type="number" name="mobile" mobile required></div>

mutli: true :指的是在 NG_VALIDATORS 这个 Token 下可以挂不同 useValue 属性所表示的值。

注意: 在模板式表单中, 是不可以在模板中使用字段的状态属性的。 模板式表单与深入了解Angular中的表單不同, 它的模型的值和它状态的变更是异步的, 而且很难控制。
如果想要使用字段的状态属性,我们可以进行如下操作:

// .html文件中
<div>  
   用户名:<input ngModel type="text" minlength="6" name="username" (input)="onUsernameInput(myForm)" required>
</div>
<div [hidden]="usernameValid || usernameUntouched">  
    <div [hidden]="!myForm.form.hasError(&#39;required&#39;, &#39;username&#39;)">
      用户名是必填项!
    </div>  
    <div [hidden]="!myForm.form.hasError(&#39;minlength&#39;, &#39;username&#39;)">
      用户名长度至少是6位!
    </div>
</div>
// .ts文件中
usernameValid = true; 
usernameUntouched = true; 
onUsernameInput(form: NgForm): void {  
   if (form) {
      this.usernameValid = form.form.get(&#39;username&#39;).valid;    
      console.log(&#39;valid&#39;, this.usernameValid);          
      this.usernameUntouched = form.form.get(&#39;username&#39;).untouched;   
      console.log(&#39;untouched&#39;,   this.usernameUntouched);
    }
}

小结: 在使用字段的状态属性时, 深入了解Angular中的表單比模板式表单更方便,可以节省很多代码,而且比较可控。所以模板式表单适合用于一些简单的场景。

更多编程相关知识,请访问:编程视频!!

以上是深入了解Angular中的表單的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除