小編給大家分享一下Angular2如何實現(xiàn)響應(yīng)式表單,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供府谷企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、HTML5、小程序制作等業(yè)務(wù)。10年已為府谷眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。
響應(yīng)式表單介紹
angular提供了兩種表單搭建技術(shù): 響應(yīng)式表單和模板驅(qū)動式表單。都依賴于@angular/forms庫,并共享了一些通用的表單控件集。
但是他們在原理、代碼風(fēng)格以及技術(shù)上存在區(qū)別。他們甚至有自己的模塊:ReactiveFormsModule以及FormsModule。
響應(yīng)式表單(ReactiveFormsModule):
anguar的響應(yīng)式表單簡化了管理數(shù)據(jù)時響應(yīng)式風(fēng)格的編碼實現(xiàn),使用了在無視圖數(shù)據(jù)模型(從服務(wù)器獲取)以及以視圖為導(dǎo)向的模型用于保持屏幕上HTML控件顯示的值與狀態(tài)。響應(yīng)式表單提供了響應(yīng)式模式測試以及驗證上的便利。
使用響應(yīng)式表單,你將在組件類中創(chuàng)建一個anular的表單控件樹對象,并在組件模板中使用提供的技術(shù)綁定到原生表單控件標(biāo)簽中。
你直接在組件類中創(chuàng)建并操作控件對象。因為組件類能直接訪問到數(shù)據(jù)模型以及表單控件結(jié)構(gòu),你可以將數(shù)據(jù)模型值推送到表單控件以及將用戶的更改響應(yīng)到后邊來。組件可以觀察表單控件狀態(tài)的更改并響應(yīng)這些更改。
直接使用表單控件對象工作的一個好處是值以及驗證的更新總能夠同步完成并受你控制。你不會遇到有時候因為模板驅(qū)動表單造成的時間問題,并且響應(yīng)式表單更易測試。
為了保持響應(yīng)的一致性,組件會保存不一致的數(shù)據(jù)模型,將其視為純粹的原始值。不會直接更新數(shù)據(jù)模型,組件會提取用戶的更改并轉(zhuǎn)發(fā)到外面的組件或服務(wù)中,(可能是用來保存他們的)并返回一個新數(shù)據(jù)模型到組件,用于響應(yīng)模型狀態(tài)的更新。
使用響應(yīng)式表單指令不需要你依賴于全部響應(yīng)式原理,但是這確實能促進(jìn)響應(yīng)式編程方法如果你選擇了要使用這個方法的話。
模板驅(qū)動式表單(FormsModule):
模板驅(qū)動式的表單使用了完全不同的方式。
你在組件模板中放置HTML表單控件(input這些)并使用比如ngModel這些指令綁定到數(shù)據(jù)模型屬性。
你不需要創(chuàng)建angular表單控件對象,因為angular會根據(jù)你的數(shù)據(jù)綁定信息自動幫你創(chuàng)建出來。你不是推送或者拉取數(shù)據(jù)值。angular在ngModel中幫你處理了。angular會更新那些被改變的數(shù)據(jù)值。
出于這個原因,ngModel不再是ReactiveFormsModule的一部分了。
這意味著可以在組件類中寫更少的代碼,不過模板驅(qū)動表單是異步工作的,這可能會在某些情況下復(fù)雜化開發(fā)。
同步vs異步
響應(yīng)式表單是同步的。模板驅(qū)動表單是異步的,這是其區(qū)別的根源。
在響應(yīng)式表單中,你在代碼中創(chuàng)建一個完整的表單控件樹。你可以從子表單或父表單中立即更新或取回一個值,因為所有的控件都可訪問到。
模板驅(qū)動表單將他們的表單控件的創(chuàng)建委托給了指令。為了避免“檢查后又更改”的錯誤,這些指令使用了不止一個循環(huán)來建立整個控件樹。這意味著你必須在操作任何組件類中的空間表單時等那么一小會兒。
比如說,如果你使用@ViewChild(NgForm)查詢注入到表單控件中并在ngAfterViewInit這個生命周期鉤子中檢查它,你將發(fā)現(xiàn)它沒有子元素。你必須等一會,使用setTimeout來等待,然后你才能從這個空間中去除值并驗證它或者將它設(shè)置為新的值。
模板驅(qū)動表單的異步性同時復(fù)雜化了單元測試。你必須使用async()或者fakeAsync()來包裝你的測試塊來避免找不到表單的值。而如果使用的是響應(yīng)式表單,一切都如你所愿的存在著。
哪一個方式更好?
沒有哪種是更好的。他們是兩種不同的搭建方式,各自擁有長處和短處。使用最適合你的方式才是對的。在一個應(yīng)用中你可能兩種方式都要使用到。
本文僅僅會描述響應(yīng)式的范例與精華所在。對于模板驅(qū)動式表單,可以前往表單介紹頁。
接下來你將寫出你自己的項目來演示響應(yīng)式表單。然后你將學(xué)會關(guān)于angular表單類以及如何在響應(yīng)式表單中使用它。
對上文的總結(jié)就是,相比ng1中數(shù)據(jù)的雙向綁定,ng2保留了這個雙向綁定能力(底層其實優(yōu)化了很多),原先的ng-model指令升級成了ngModel,使用的功能保持不變。
同時盡管ng2版本的數(shù)據(jù)雙向綁定得到了很大的優(yōu)化,仍改變不了其數(shù)據(jù)異步綁定的方式,因為ng2不能確定數(shù)據(jù)何時綁定,我們也不能確定很多網(wǎng)絡(luò)請求得到的數(shù)據(jù)到來的時間。
在ng1中其實這個機制會有一些尷尬的場景,至少筆者在一些情況下不得不在一些業(yè)務(wù)場景下使用setTimeout來保證數(shù)據(jù)已經(jīng)成功綁定進(jìn)入scope的watch循環(huán),但這個異步綁定數(shù)據(jù)又是不可避免的,除非我們自己來適應(yīng)實際項目改寫angular代碼了。
所以ng2就提供了讓我們配合具體項目場景改寫ngModel的能力,也就是原文介紹的響應(yīng)式表單。
其跟ngModel的關(guān)系就是,ngModel是響應(yīng)式表單的官方實現(xiàn),其在我們綁定數(shù)據(jù)時自動為我們實現(xiàn)響應(yīng)式表單中用到的幾個機制,如果我們需要數(shù)據(jù)嚴(yán)格的實時同步綁定,就不必使用ngModel,可以親自來編寫響應(yīng)式的表單,步驟覆蓋了組件模板到數(shù)據(jù)模型類整條龍,而這么多事情在合適的場景下使用ngModel已經(jīng)可以實現(xiàn)了,這兩種表單綁定的方式各有其優(yōu)勢。
1. 使用響應(yīng)式表單
響應(yīng)式表單的能力封裝在ReactiveFormsModule中,并且跟FormsModule同時包含在@angular/forms這個包中。
表單類的要點:
1.AbstractControl是FormControl、FormGroup、FormArray這三個實例表單類的抽象基類。它提供了他們的通用行為以及屬性,其中就有observable。
2.FormControl在單個表單控件中檢查值并驗證狀態(tài)。它負(fù)責(zé)將其通知給HTML表單控件(比如input這些)。
3.FormGroup負(fù)責(zé)AbstractControl實例的一個組的值與驗證狀態(tài)。組的屬性包含了它們的子控件。你的組件的頂級表單就是一個FormGroup。
4.FormArray負(fù)責(zé)AbstractControl實例的數(shù)值索引數(shù)組的值與狀態(tài)驗證。
2. FormControl
最核心的指令就是FormControl,算是底層的ngModel,在模板標(biāo)簽中跟定義好的數(shù)據(jù)模型字段綁定起來,就像這樣:
Hero Detail
Just a FormControl
同時在組件代碼中需要將上例中這個name字段聲明為FormControl類:
export class HeroDetailComponent1 { name = new FormControl(); }
3. FormGroup
將多個FormControl對象分組到FormGroup中,用來方便管理。定義方法如下:
import { Component } from '@angular/core'; import { FormControl, FormGroup } from '@angular/forms'; export class HeroDetailComponent2 { heroForm = new FormGroup ({ name: new FormControl() }); }
此時模板標(biāo)簽中也要分組來寫:
Hero Detail
FormControl in a FormGroup
現(xiàn)在的效果就是可以從heroForm中實時讀取到其值和一些附加的狀態(tài)的變化。
可以在模板中添加兩個標(biāo)簽來展示數(shù)據(jù)的更改:
Form value: {{ heroForm.value | json }}
Form status: {{ heroForm.status | json }}
4. FormBuilder
還有個新概念就是FormBuilder,是用來幫助創(chuàng)建表單類的:
1. 顯示聲明heroForm屬性的類型為FormGroup,后面你將會初始化它
2. 注入FormBuilder到構(gòu)造器中
3. 使用FormsBuilder添加新方法定義heroForm,叫做createForm。
4. 在構(gòu)造器中執(zhí)行createForm方法。
export class HeroDetailComponent3 { heroForm: FormGroup; // <--- heroForm is of type FormGroup constructor(private fb: FormBuilder) { // <--- inject FormBuilder this.createForm(); } createForm() { this.heroForm = this.fb.group({ name: '', // <--- the FormControl called "name" }); } }
上例中執(zhí)行createForm方法即可動態(tài)快速的創(chuàng)建出表單類,其在一些表單類需要更改的場景下可以使用。
5. setValue和patchValue
這兩個方法是真正給表單模型賦值用的。因為表單顯示的數(shù)據(jù)與真實的底層數(shù)據(jù)肯定不能使同一個,否則表單輸入數(shù)據(jù)一旦更改,源數(shù)據(jù)就被污染了,而這兩個方法就是用來將源數(shù)據(jù)賦值到表單模型數(shù)據(jù)上的。
每當(dāng)需要賦值時就可以調(diào)用,其中setValue必須準(zhǔn)確賦值,并且會在數(shù)據(jù)不匹配時報告錯誤;而patchValue沒有這么嚴(yán)格,但可以傳一個對象,且不匹配時不會報告錯誤。
而我們要做的就是在ng2組件的ngOnChanges回調(diào)中手動執(zhí)行setValue設(shè)置數(shù)據(jù)值。比如這樣:
ngOnChanges() this.heroForm.setValue({ name: this.hero.name, address: this.hero.addresses[0] || new Address() }); }
同時ng2還提供了一個reset方法來重新調(diào)用setValue方法(setValue本身好像只是用來一次性賦值的)。
6. FormArray
FormArray是用來對付FormGroups列表的,比如一個英雄有可能有多個address字段,address字段本身就是個FormGroup,此時就要用到FormArray了:
this.heroForm = this.fb.group({ name: ['', Validators.required ], secretLairs: this.fb.array([]), // <-- secretLairs as an empty FormArray power: '', sidekick: '' });
獲取FormArray要用到FormGroup提供的一個get方法:
get secretLairs(): FormArray { return this.heroForm.get('secretLairs') as FormArray; };
其顯示的模板如下:
以上是“Angular2如何實現(xiàn)響應(yīng)式表單”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!