You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mat-Dialog回传数据时afterClosed内FormArray patchValue不生效问题

问题根因
  • 弹窗生命周期钩子写法错误:将ngOnInit写为OnInit,Angular无法识别执行初始化逻辑,表单初始赋值、valueChanges订阅都不会生效。
  • 弹窗回传数据格式错误:save()方法里用[this.data.qty]把qty包成了单元素数组回传,父组件拿到的result是数组而非预期的数值/对象,循环、取值逻辑全部失效。
  • 父组件FormArray的子项结构不匹配:CreatesetItem()生成的FormGroup仅包含ListItem控件,不存在qty字段,调用patchValue({ qty: xxx })时找不到对应控件,自然无法更新渲染。
  • 重复操作残留脏数据:每次打开弹窗回调里直接往setItem里push新项,没有清空之前的旧控件,多次操作会产生冗余表单项。
  • 赋值逻辑错误:就算回传格式正确,result.qty的取值也和回传结构不匹配,拿不到有效值;且setValue本身无返回值,原代码中将其返回值赋给this.data属于无效写法。
修复方案

1. 修正弹窗组件逻辑

// 弹窗组件代码
ngOnInit(): void {
  this.fg = this.fb.group({
    id: [],
    qty: [],
    displayArray: this.fb.array([this.CreateItem()]),
  });
  this.fg.get('qty').valueChanges.subscribe((res) => {
    // 增加边界判断,避免非法值报错
    if (typeof res !== 'number' || res < 0) return;
    // 数量减少时移除多余表单项,不要只加不减
    while (this.displayArray.length > res) {
      this.displayArray.removeAt(this.displayArray.length - 1);
    }
    for (let i = this.displayArray.length; i < res; i++) {
      this.displayArray.push(this.CreateItem());
    }
  });
  // setValue无返回值,直接调用即可
  this.fg.get('qty').setValue(this.data.qty);
}

CreateItem(): FormGroup {
  return this.fb.group({
    MoreItem: [''],
  });
}

get displayArray(): FormArray {
  return this.fg.get('displayArray') as FormArray;
}

save() {
  // 回传结构化对象,不要包无意义的数组
  this.dialogRef.close({
    qty: this.fg.value.qty,
    displayItems: this.fg.value.displayArray
  });
}

2. 修正父组件FormArray逻辑

// 父组件代码
CreatesetItem(): FormGroup {
  // 补全需要的表单字段,和后续赋值的属性一一对应
  return this.fb.group({
    ListItem: [''],
    qty: [] // 原代码漏了该控件,是patchValue不生效的核心原因之一
  });
}

get setItem(): FormArray {
  return this.fg.get('setItem') as FormArray;
}

get Info(): FormArray {
  return this.fg.get('Info') as FormArray;
}

openAlertDialog(index: number) {
  const dialogRef = this.dialog.open(AlertDialogComponent, {
    data: {
      qty: this.fg.value.Info[index].qty,
      name: this.fg.value.Info[index].name,
    },
  });
  dialogRef.afterClosed().subscribe((result) => {
    // 用户点遮罩、ESC取消弹窗时result为undefined,直接终止逻辑
    if (!result) return;
    // 先清空旧的表单项,避免重复堆积
    while (this.setItem.length) {
      this.setItem.removeAt(0);
    }
    // 按回传的数量生成新表单项
    for (let i = 0; i < result.qty; i++) {
      const newItem = this.CreatesetItem();
      newItem.patchValue({
        qty: result.qty,
        ListItem: result.displayItems[i]?.MoreItem || ''
      })
      this.setItem.push(newItem);
    }
    // 同步更新Info数组对应项的qty值
    this.Info.at(index).patchValue({ qty: result.qty });
  });
}
极端场景兼容

如果组件使用OnPush变更检测策略,赋值后视图未正常刷新,可注入ChangeDetectorRef,在赋值逻辑末尾调用this.cdr.markForCheck()手动触发视图更新即可。

内容的提问来源于stack exchange,提问作者Yan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.31 11:01:40