浅析Angular中怎么结合使用FormArray和模态框

 2903

怎么结合使用FormArray模态框?下面本篇文章给大家介绍一下Angular的FormArray和模态框结合使用的方法,希望对大家有所帮助!


浅析Angular中怎么结合使用FormArray和模态框


业务场景

使用FormArray制作动态表单。每创建一个表单,页面就新增一个input显示表单填写的标题,点击编辑再跳转到点击表单的填写内容。

  1. // 封装获取modelList
  2. get modelList() {
  3.     return this.formGroup.get('modelList') as FormArray
  4. }
  5. constructor(private fb: FormBuilder) {}
  6. ngOnInit() {
  7.     // 一开始初始化arr为空数组
  8.     this.formGroup = this.fb.group({
  9.         // 内部嵌套FormControl、FormArray、FormGroup
  10.         modelList: this.fb.array([])
  11.     })
  12. }
  13. // 模态框构造内部的表单
  14. function newModel() {
  15.     return this.fb.group({
  16.         modelName: [''],
  17.         // 可以继续嵌套下去,根据业务需求
  18.     })
  19. }
  20. // 省略模态框部分代码
  21. // 传递到模态框的FormArray
  22. selectedType: FormArray

表单列表

浅析Angular中怎么结合使用FormArray和模态框

表单详情【模态框】

浅析Angular中怎么结合使用FormArray和模态框


  1. <form [FormGroup]="formGroup">
  2.     <div FormArrayName="modelList">
  3.         <ng-container *nfFor="let item of modelList.controls;let i = index" [FormGroupName]="i">
  4.             <nz-input-group
  5.                 [nzSuffix]="suffixIconSearch"
  6.               >
  7.                 <input type="text" nz-input formControlName="modelName"/>
  8.               </nz-input-group>
  9.               <ng-template #suffixIconSearch>
  10.                 <span
  11.                   nz-icon
  12.                   nzType="edit"
  13.                   class="hover"
  14.                   (click)="showModal(i)"
  15.                 ></span>
  16.               </ng-template>
  17.         </ng-container>
  18.     </div>
  19. </form>
  20. <nz-modal
  21.   [(nzVisible)]="isVisible"
  22.   nzTitle="Model"
  23.   [nzFooter]="modalFooter"
  24.   (nzOnCancel)="handleCancel()"
  25.   (nzOnOk)="handleOk()"
  26. >
  27.   <ng-container *nzModalContent>
  28.     <form nz-form [formGroup]="selectedType">
  29.       <nz-form-item>
  30.         <nz-form-label nzRequired>Model Test</nz-form-label>
  31.         <nz-form-control>
  32.           <input
  33.             type="text"
  34.             nz-input
  35.             placeholder="请输入ModelName"
  36.             formControlName="modelName"
  37.           />
  38.         </nz-form-control>
  39.       </nz-form-item>
  40.       <nz-form-item>
  41.         <nz-form-control>
  42.           <product-config></product-config>
  43.         </nz-form-control>
  44.       </nz-form-item>
  45.     </form>
  46.   </ng-container>
  47.   <ng-template #modalFooter>
  48.     <button *ngIf="!isNewModel" nzDanger nz-button nzType="default" (click)="handleDelete()">删除</button>
  49.     <button *ngIf="isNewModel" nz-button nzType="default" (click)="handleCancel()">取消</button>
  50.     <button nz-button nzType="primary" (click)="handleOk()">保存</button>
  51.   </ng-template>
  52. </nz-modal>

由于这种模态框比较特殊,割裂了表单的FormGroup之间的关系,在点击的时候需要传递参数到模态框显示部分值,如果单纯传递参数使用this.modelList.at(index)获取实体到模态框上进行赋值修改,在模态框点击保存后会发现修改的值没有在表单更新,而表单上对input值修改发现可以影响到模态框的内容。

但是模态框新增的表单却可以响应到页面中去。

原错误代码思路

点击编辑后,将点击的FormArray的元素传递给一个临时变量 this.selectedType = <FormGroup>this.modelList.at(index);,并且对模态框表单传值。

模态框点击保存再将原FormArray的值重新替换

  1. this.modelList.removeAt(this.modelIndex)
  2. this.modelList.insert(this.modelIndex, this.selectedType)

点击新增,创建一个新的FormGroup对象

保存添加push到原页面的FormArray中

  1. newModelType(): FormGroup {
  2.     return this.fb.group({
  3.       modelName: ['', Validators.required],
  4.       configList: this.fb.array([]),
  5.     });
  6.   }
  7. // ...省略
  8. // 模态框显示
  9. show() {
  10.     this.isVisible = true
  11.     this.selectedType = this.newModelType();
  12. }
  13. // 保存
  14. save() {
  15.     this.isVisible = false
  16.     // 原页面FormArray
  17.     this.modelList.push(this.selectedType);
  18. }

最后发现这种写法只能够单向改变,页面外input修改值会影响到模态框,但是模态框的值改变保存却让外部没有更新。通过console方式查看页面的FormArray内部参数发现其实是有改变的,只是angular没有检测到。这个时候判断没有发生响应的原因一般是没有触发angular检测机制,仔细查看文档发现有一行很重要 angular文档在最下面写着

浅析Angular中怎么结合使用FormArray和模态框

原本第一次阅读的时候,觉得我遵守了这种原则,因为在编辑的时候,我选择了操控原FormArray进行元素删除和插入,是遵循了这种规则,但是实际上在模态框赋值就已经违反了这种原则,我在赋值的时候拿了FormArray的元素实例赋值给模态框的临时变量,然后更改实例的值,又重新删除插入,本质上我操作的是同一个实例,所以angular没有检测到发生变化【虽然值发生改变】


浅析Angular中怎么结合使用FormArray和模态框


所以正确的做法是啥??

在赋值的地方不能偷懒,仍然要重新创建新对象,再拿原对象的赋值。【相当于深拷贝】

  1. this.selectedType = this.newModelType();
  2. const old = this.modelList.at(index);
  3. this.selectedType.setValue({
  4.   'modelName': old.get('modelName').value
  5. })

这时候就可以正常更新了。

总结

其实查到最后本质上还是回归文档。在排查错误也走了很多坑,而且国内基本没什么angular的文章,还得靠外网论坛去找问题。


本文网址:https://www.zztuku.com/detail-13614.html
站长图库 - 浅析Angular中怎么结合使用FormArray和模态框
申明:本文转载于《掘金社区》,如有侵犯,请 联系我们 删除。

评论(0)条

您还没有登录,请 登录 后发表评论!

提示:请勿发布广告垃圾评论,否则封号处理!!

    编辑推荐