使用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
相关产品推荐
相关产品推荐

