成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

Angular中響應(yīng)式表單的三種更新值方法詳析

前言

成都創(chuàng)新互聯(lián)公司是一家專注于網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)與策劃設(shè)計,霍山網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)十年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:霍山等地區(qū)?;羯阶鼍W(wǎng)站價格咨詢:13518219792

眾所周知Angular響應(yīng)式表單相比較模板驅(qū)動表單更大操作性、更易測試性。因此,我更推薦這類表單創(chuàng)造方式。

當(dāng)一個用于修改用戶信息的表單,數(shù)據(jù)的來源總是來自遠程;而對于一個 FormGroup 的創(chuàng)建總在 ngOnInit 中完成。因此,這里會有一個表單更新值的問題。

而通常我們會透過 FormGroup 下的三種方式 setValue、patchValue、reset 將值寫入表單當(dāng)中。

當(dāng)然,或許我說的這三種方式時你壓根就沒有做過,那說明在表單上你依賴的是雙向綁定 [(ngModel)],這本身就不是符合 Angular 響應(yīng)式表單的牛B之處了。因此,在此我們不討論這種這種方式。下面來一起看看詳細的介紹:

一、創(chuàng)建響應(yīng)式表單

我們模擬一個用戶信息修改的表單所需要的字段,可能包括:email、nickname 等。

如果以API的方式與現(xiàn)實字段之間產(chǎn)生一個關(guān)聯(lián),那么 FormGroup 表示一個表單,F(xiàn)ormControl 表示表單中的字段。因此,F(xiàn)ormControl 必須包裹在 FromGroup 下面。

下面,我們先簡單的構(gòu)建一個響應(yīng)式表單。

別忘記導(dǎo)入 ReactiveFormsModule 模塊。

@Component({
 selector: 'app-validation',
 template: `
 <form [formGroup]="form" (ngSubmit)="_submitForm(form)">
 <input type="email" formControlName="email">
 <input type="text" formControlName="nickname">
 <button type="submit" [disabled]="form.invalid">Submit</button>
 </form>
 `
})
export class UserEditComponent {
 constructor(private fb: FormBuilder, private route: ActivatedRoute) {}
 
 ngOnInit() {
 this.form = this.fb.group({
  email: ['', Validators.compose([Validators.required, Validators.email])],
  nickname: ['', [Validators.required]]
 });
 
 this.route.params
  .switchMap((params: Params) => loadUser(+params['id']))
  .subscribe(data => {
  // Updating value
  });
 }
 
 loadUser() {
 return Observable.of({ email: 'xx@xx.com', nickname: 'cipchk' }).delay(1000);
 }
 
 _submitForm({ value }) {
 // Save value
 }
}

以上的這些代碼再熟悉不過了。假設(shè) UserEditComponent 是由路由 /user/edit/1 觸發(fā),那么會發(fā)生幾個幾件事情。

首先,創(chuàng)建一個空的響應(yīng)式表單 form。

this.form = this.fb.group({
 email: ['', Validators.compose([Validators.required, Validators.email])],
 nickname: ['', [Validators.required]]
});

表單的內(nèi)容有 email、nickname 兩個字段。

  • email 必填項且必須是標(biāo)準(zhǔn) Email 格式。
  • nickname 必填項。

然而,HTML中,除了 formGroup、formControlName 的配置以外,也看不到任何有關(guān)對表單的校驗代碼。但,當(dāng)我們輸入一個無效 Email 時 input 會自動加上 ng-invalid 類。

這便是響應(yīng)式表單的魅力。

現(xiàn)在我們回到正題,將分別針對 setValue、patchValue、reset 三種不同更新表單值實際上會發(fā)生什么。

二、patchValue

正如名稱那般,打補丁。假如我們在 email 文本框里輸入:xx@xx.com,接著調(diào)用:

this.form.patchValue({ nickname: 'cipchk' });

最終的結(jié)果是兩個字段同時擁有值,因為這里我們只對 nickname 設(shè)置了值,而 email 并沒有,那只是先前人為錄入的數(shù)據(jù)。

那么 patchValue 實際上做了什么呢?

patchValue(value: {[key: string]: any}, options: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
 Object.keys(value).forEach(name => {
 if (this.controls[name]) {
 this.controls[name].patchValue(value[name], {onlySelf: true, emitEvent: options.emitEvent});
 }
 });
 this.updateValueAndValidity(options);
}

首先,利用 Object.keys 查找主鍵,并以主鍵名查找相應(yīng)的 FromControl 實例對象:

Object.keys({ nickname: 'cipchk' }).forEach(name => { 
 console.log(name); 
});
// [ 'nickname' ]

然后,更新值:

this.controls[name].patchValue(value[name], {onlySelf: true, emitEvent: options.emitEvent});

而 FromControl 實例的 patchValue 和 FromGroup 不同,他只是單純的更新 FromControle 實例對象中的 value 值。

value 相當(dāng)于表單實際值,還記得先前HTML中的 formControlName 就是將實例與DOM產(chǎn)生聯(lián)系,這也就是為什么不需要在DOM中使用雙向綁定的原因。

三、setValue

跟 patchValue 有一點不一樣,當(dāng)我們提供一個 FromGroup 中并不存在的字段時,會拋出一個錯誤。除此之外,與 patchValue 并無不同。

setValue(value: {[key: string]: any}, options: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
 this._checkAllValuesPresent(value);
 Object.keys(value).forEach(name => {
 this._throwIfControlMissing(name);
 this.controls[name].setValue(value[name], {onlySelf: true, emitEvent: options.emitEvent});
 });
 this.updateValueAndValidity(options);
}

主要是 this._throwIfControlMissing(name); 當(dāng)傳遞的對象有一個不是 FromControl 時直接拋棄一個 Error。

_throwIfControlMissing(name: string): void {
 if (!Object.keys(this.controls).length) {
 throw new Error(`
 There are no form controls registered with this group yet. If you're using ngModel,
 you may want to check next tick (e.g. use setTimeout).
 `);
 }
 if (!this.controls[name]) {
 throw new Error(`Cannot find form control with name: ${name}.`);
 }
}

四、reset

正常情況下,表單需要提供一個重置按鈕時調(diào)用此方法。

reset(formState: any = null, options: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
 this._applyFormState(formState);
 this.markAsPristine(options);
 this.markAsUntouched(options);
 this.setValue(this._value, options);
}

除了恢復(fù)校驗狀態(tài)以外。最后一句代碼是調(diào)用 setValue,這等同上一節(jié)說的。因此,當(dāng)我們調(diào)用此方法時,允許我們直接傳遞一個數(shù)據(jù)對象做為重置后的默認值,比如:

<button (click)="form.reset({ nickname: 'xx' })">Reset</button>

重置表單后并設(shè)置 nickname 默認值為:xx。

結(jié)論

每一種不同更新值方式都會有不一樣的結(jié)果,當(dāng)我們回頭過看開頭中留下來的:

// Updating value

如果是你,你會怎么寫呢?

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對創(chuàng)新互聯(lián)的支持。

當(dāng)前題目:Angular中響應(yīng)式表單的三種更新值方法詳析
文章源于:http://jinyejixie.com/article22/pgejcc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站App設(shè)計、定制開發(fā)、外貿(mào)建站、面包屑導(dǎo)航、電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都app開發(fā)公司
繁峙县| 色达县| 大丰市| 略阳县| 普安县| 永修县| 皮山县| 泰宁县| 黄冈市| 化州市| 仁怀市| 迭部县| 宣汉县| 长顺县| 峨眉山市| 甘德县| 遵化市| 策勒县| 克什克腾旗| 仙桃市| 昔阳县| 屯昌县| 无极县| 潼关县| 丰顺县| 赤城县| 尼木县| 淳安县| 衡南县| 隆子县| 怀远县| 湛江市| 琼结县| 聂拉木县| 龙岩市| 麻栗坡县| 宜兴市| 霞浦县| 淮南市| 海安县| 东阳市|