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

使用Angular动态添加mat-expansion-panel面板未生效如何解决

问题排查

你当前代码存在以下几个核心问题:

  • mat-accordion是Angular Material手风琴组件的容器标签,你将它放在了*ngFor循环内部,导致每个面板都被单独包裹在独立的手风琴容器中,新增面板不会和原有面板渲染在同一组内
  • 新增FormControl的名称固定为abc,多次点击添加按钮会因为FormGroup内存在重名控件抛出错误,也不符合动态新增的业务逻辑
  • 未给*ngFor配置trackBy函数,部分场景下会出现数组更新后视图未重新渲染的异常

修改后的代码

1. HTML部分

<button class="addSection" title="Add Section" (click)="add()"></button>

<form [formGroup]="form" (ngSubmit)="onSubmit()">
  <!-- 把mat-accordion移到循环外部,作为所有面板的公共容器 -->
  <mat-accordion>
    <ng-container *ngFor="let group of formData.groups; trackBy: trackByGroupName">
      <!-- Panels-->
      <mat-expansion-panel cdkDrag>
        <mat-expansion-panel-header>
          {{group.formGroupName}}
        </mat-expansion-panel-header>
        <div [formGroupName]="group.formGroupName">
          <div class="row" style="margin-left:20px;">
            <ng-container *ngFor="let field of group.fields">
              <!--Field Rows-->
                  Data
              <!--Fields-->
            </ng-container>
          </div>
        </div>
      </mat-expansion-panel>
    </ng-container>
  </mat-accordion>
</form>

2. TS部分

首先在组件类中新增一个计数器变量用来生成唯一的面板名,再新增trackBy函数:

// 组件类中新增变量,用来生成唯一面板标识
sectionCount = 1;

// 新增trackBy函数优化ngFor渲染
trackByGroupName(index: number, group: any): string {
  return group.formGroupName;
}

add() {
  // 生成唯一的控件名,避免重名冲突
  const groupName = `section_${this.sectionCount++}`;
  this.form.addControl(groupName, new FormGroup({}));
  this.formData.groups = [...this.formData.groups, {
    formGroupName: groupName,
    fields: []
  }];
}

验证说明

修改后点击添加按钮,会在当前所有面板的末尾新增一个空面板,和你预期的在contact面板旁新增的效果一致,如果需要调整新增面板的插入位置,修改数组拼接的逻辑即可。

内容的提问来源于stack exchange,提问作者Mr.M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 17:27:07