Angular 12 表格值在modal-body添加edit form后消失如何修复
问题根因
- 你把Modal组件写在了
*ngFor循环的表格行<tr>内部,每一行都会生成一个id为exampleModalScrollable的模态框,重复ID导致DOM渲染冲突,触发表格布局异常 - Bootstrap模态框的规范要求模态框组件尽量放在页面根级节点,不要嵌套在表格、弹性盒等有特殊布局规则的容器内,否则模态框的fixed定位会受父级堆叠上下文影响,连带触发父容器(表格行)的布局计算异常
- 你使用的是原生Bootstrap的data属性触发模态框,和Angular的变更检测结合时,嵌套在循环内的模态框频繁触发重绘,会导致表格行渲染丢失
- 你测试时输入1000字长段落没有问题,是因为纯文本没有触发模态框的布局定位异常,表单的input元素有独立的默认盒模型,嵌套在循环内时触发了浏览器的表格布局重排bug
修复方案
第一步:把模态框移到表格外部
模态框不要放在*ngFor循环里,整个页面只保留一个模态框实例,点击编辑按钮时把当前选中的行数据传给表单即可。
第二步:给编辑按钮加点击事件绑定当前行数据
原来的data-target触发方式改成Angular事件绑定,点击时记录当前编辑的entry,再手动打开模态框。
第三步:补全表单的FormGroup关联逻辑
你现有的表单没有绑定FormGroup实例,需要在TS代码中补充表单定义。
修复后HTML代码示例
<div class="jumbotron"> <h3 class='text-center'>Pending Entries</h3> </div> <table class="table"> <thead> <tr> <th scope="col">Pincode</th> <th scope="col">MajorDS A</th> <th scope="col">MinorDS A</th> <th scope="col">MajorDS B</th> <th scope="col">MinorDS B</th> <th scope="col">Action</th> </tr> </thead> <tbody> <tr *ngFor="let entry of collection"> <td>{{entry.pincode}}</td> <td>{{entry.majorDamageInSubdivision_A}}</td> <td>{{entry.minorDamageInSubdivision_A}}</td> <td>{{entry.majorDamageInSubdivision_B}}</td> <td>{{entry.minorDamageInSubdivision_B}}</td> <td> <i type="button" class="fa fa-edit" (click)="openEditModal(entry)" style="font-size:30px;color:rgb(25, 0, 255)"></i> <i type="button" class="fa fa-trash" (click)="openDeleteModal(entry)" style="font-size:30px;color:red"></i> </td> </tr> </tbody> </table> <!-- 模态框移到表格外部,全局唯一 --> <div class="modal fade" id="exampleModalScrollable" tabindex="-1" role="dialog" aria-labelledby="exampleModalScrollableTitle" aria-hidden="true"> <div class="modal-dialog modal-dialog-scrollable" role="document"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalScrollableTitle">Edit & Update Entry</h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <!-- 绑定FormGroup --> <form [formGroup]="editForm"> <div class="form-group"> <label>Pincode</label> <input type="text" class="form-control" placeholder="Enter Pincode" formControlName="pincode"> <br> <label>Major Damage Score in Subdivision A</label> <input type="text" class="form-control" formControlName="majorDamageInSubdivision_A"> <br> <label>Minor Damage Score in Subdivision A</label> <input type="text" class="form-control" formControlName="minorDamageInSubdivision_A"> <br> <label>Major Damage Score in Subdivision B</label> <input type="text" class="form-control" formControlName="majorDamageInSubdivision_B"> <br> <label>Minor Damage Score in Subdivision B</label> <input type="text" class="form-control" formControlName="minorDamageInSubdivision_B"> <br> </div> </form> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <button type="button" class="btn btn-primary" (click)="saveEdit()">Save changes</button> </div> </div> </div> </div>
对应TS代码示例
import { FormBuilder, FormGroup } from '@angular/forms'; declare var $: any; // 依赖原生Bootstrap的jQuery方法打开模态框需声明 export class YourComponent { collection: any[] = []; editForm: FormGroup; currentEditEntry: any; constructor(private fb: FormBuilder) { this.editForm = this.fb.group({ pincode: [''], majorDamageInSubdivision_A: [''], minorDamageInSubdivision_A: [''], majorDamageInSubdivision_B: [''], minorDamageInSubdivision_B: [''] }) } openEditModal(entry: any) { this.currentEditEntry = entry; // 给表单赋值当前行数据 this.editForm.patchValue(entry); // 打开模态框 $('#exampleModalScrollable').modal('show'); } saveEdit() { // 保存逻辑:把表单值更新到当前条目或提交接口 Object.assign(this.currentEditEntry, this.editForm.value); $('#exampleModalScrollable').modal('hide'); } openDeleteModal(entry: any) { // 补充删除逻辑即可 } }
可选优化
建议替换原生Bootstrap为ng-bootstrap模态框组件,无需依赖jQuery,和Angular生态适配性更好,不会出现此类渲染冲突。
内容的提问来源于stack exchange,提问作者Sam1729
相关产品推荐
相关产品推荐

