Angular的FormArray和模態(tài)框結合使用實例詳解
業(yè)務場景
使用FormArray制作動態(tài)表單。每創(chuàng)建一個表單,頁面就新增一個input顯示表單填寫的標題,點擊編輯再跳轉到點擊表單的填寫內(nèi)容。
// 封裝獲取modelList
get modelList() {
return this.formGroup.get('modelList') as FormArray
}
constructor(private fb: FormBuilder) {}
ngOnInit() {
// 一開始初始化arr為空數(shù)組
this.formGroup = this.fb.group({
// 內(nèi)部嵌套FormControl、FormArray、FormGroup
modelList: this.fb.array([])
})
}
// 模態(tài)框構造內(nèi)部的表單
function newModel() {
return this.fb.group({
modelName: [''],
// 可以繼續(xù)嵌套下去,根據(jù)業(yè)務需求
})
}
// 省略模態(tài)框部分代碼
// 傳遞到模態(tài)框的FormArray
selectedType: FormArray
表單列表

表單詳情【模態(tài)框】

<form [FormGroup]="formGroup">
<div FormArrayName="modelList">
<ng-container *nfFor="let item of modelList.controls;let i = index" [FormGroupName]="i">
<nz-input-group
[nzSuffix]="suffixIconSearch"
>
<input type="text" nz-input formControlName="modelName"/>
</nz-input-group>
<ng-template #suffixIconSearch>
<span
nz-icon
nzType="edit"
class="hover"
(click)="showModal(i)"
></span>
</ng-template>
</ng-container>
</div>
</form>
<nz-modal
[(nzVisible)]="isVisible"
nzTitle="Model"
[nzFooter]="modalFooter"
(nzOnCancel)="handleCancel()"
(nzOnOk)="handleOk()"
>
<ng-container *nzModalContent>
<form nz-form [formGroup]="selectedType">
<nz-form-item>
<nz-form-label nzRequired>Model Test</nz-form-label>
<nz-form-control>
<input
type="text"
nz-input
placeholder="請輸入ModelName"
formControlName="modelName"
/>
</nz-form-control>
</nz-form-item>
<nz-form-item>
<nz-form-control>
<product-config></product-config>
</nz-form-control>
</nz-form-item>
</form>
</ng-container>
<ng-template #modalFooter>
<button *ngIf="!isNewModel" nzDanger nz-button nzType="default" (click)="handleDelete()">刪除</button>
<button *ngIf="isNewModel" nz-button nzType="default" (click)="handleCancel()">取消</button>
<button nz-button nzType="primary" (click)="handleOk()">保存</button>
</ng-template>
</nz-modal>
由于這種模態(tài)框比較特殊,割裂了表單的FormGroup之間的關系,在點擊的時候需要傳遞參數(shù)到模態(tài)框顯示部分值,如果單純傳遞參數(shù)使用this.modelList.at(index)獲取實體到模態(tài)框上進行賦值修改,在模態(tài)框點擊保存后會發(fā)現(xiàn)修改的值沒有在表單更新,而表單上對input值修改發(fā)現(xiàn)可以影響到模態(tài)框的內(nèi)容。
但是模態(tài)框新增的表單卻可以響應到頁面中去。
原錯誤代碼思路
- 點擊編輯后,將點擊的FormArray的元素傳遞給一個臨時變量
this.selectedType = <FormGroup>this.modelList.at(index);,并且對模態(tài)框表單傳值。 - 模態(tài)框點擊保存再將原FormArray的值重新替換
this.modelList.removeAt(this.modelIndex) this.modelList.insert(this.modelIndex, this.selectedType)
- 點擊新增,創(chuàng)建一個新的FormGroup對象
- 保存添加push到原頁面的FormArray中
newModelType(): FormGroup {
return this.fb.group({
modelName: ['', Validators.required],
configList: this.fb.array([]),
});
}
// ...省略
// 模態(tài)框顯示
show() {
this.isVisible = true
this.selectedType = this.newModelType();
}
// 保存
save() {
this.isVisible = false
// 原頁面FormArray
this.modelList.push(this.selectedType);
}
最后發(fā)現(xiàn)這種寫法只能夠單向改變,頁面外input修改值會影響到模態(tài)框,但是模態(tài)框的值改變保存卻讓外部沒有更新。通過console方式查看頁面的FormArray內(nèi)部參數(shù)發(fā)現(xiàn)其實是有改變的,只是angular沒有檢測到。這個時候判斷沒有發(fā)生響應的原因一般是沒有觸發(fā)angular檢測機制,仔細查看文檔發(fā)現(xiàn)有一行很重要 angular文檔 在最下面寫著

原本第一次閱讀的時候,覺得我遵守了這種原則,因為在編輯的時候,我選擇了操控原FormArray進行元素刪除和插入,是遵循了這種規(guī)則,但是實際上在模態(tài)框賦值就已經(jīng)違反了這種原則,我在賦值的時候拿了FormArray的元素實例賦值給模態(tài)框的臨時變量,然后更改實例的值,又重新刪除插入,本質上操作的是同一個實例,所以angular沒有檢測到發(fā)生變化【雖然值發(fā)生改變】
this . mode llist. removeAt ( this . mode lIndex ) this . modell ist. insert(this . modelIndex, this . se lectedType)
所以正確的做法是啥??
在賦值的地方不能偷懶,仍然要重新創(chuàng)建新對象,再拿原對象的賦值。【相當于深拷貝】
this.selectedType = this.newModelType();
const old = this.modelList.at(index);
this.selectedType.setValue({
'modelName': old.get('modelName').value
})
這時候就可以正常更新了。
總結
其實查到最后本質上還是回歸文檔。在排查錯誤也走了很多坑,而且國內(nèi)基本沒什么angular的文章,還得靠外網(wǎng)論壇去找問題。
以上就是Angular的FormArray和模態(tài)框結合使用實例詳解的詳細內(nèi)容,更多關于Angular FormArray模態(tài)框的資料請關注腳本之家其它相關文章!
相關文章
詳解Angular2表單-模板驅動的表單(Template-Driven Forms)
本篇文章主要介紹了詳解Angular2表單-模板驅動的表單(Template-Driven Forms),具有一定的參考價值,有興趣的可以了解一下2017-08-08
Angular4.0中引入laydate.js日期插件的方法教程
在AngularJs中我們會不可避免的使用第三方庫,例如jquery插件庫。下面這篇文章主要給大家介紹了關于Angular4.0中引入laydate.js日期插件的相關資料,需要的朋友可以參考借鑒,下面隨著小編來一起學習學習吧。2017-12-12

