Angular:*ngFor内用模态弹窗删除时,索引值传递错误的解决方法
问题分析
你遇到的问题核心是所有循环生成的模态框共享了同一个ID exampleModalCenter。当你点击任意一行的Remove按钮时,浏览器会匹配到页面中第一个拥有该ID的模态框,所以无论点哪一行,最终触发的都是第一行绑定的索引0和对应文档ID,这就导致了非首行点击也传首行数据的情况。
解决方案
这里提供两种常用的修复方式,你可以根据项目习惯选择:
方式一:为每个模态框生成唯一ID
利用循环的索引i为每一行的模态框和对应按钮生成唯一的ID,确保点击对应行的按钮时,触发的是该行自己的模态框。
修改后的HTML代码片段(重点修改已标注):
<ng-template #tmplt> <tr *ngFor="let kbase of Colum; let i =index"> <!-- 省略其他列代码 --> <td> <!-- 修改data-target为带索引的唯一ID --> <button class="btn btn-danger" type="button" data-toggle="modal" data-target="#exampleModalCenter-{{i}}">Remove</button> <!-- 修改模态框id为带索引的唯一ID --> <div class="modal fade" id="exampleModalCenter-{{i}}" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <!-- 省略模态框头部、内容代码 --> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <!-- 这里的i和id依然是当前循环行的正确值 --> <button type="button" class="btn btn-danger" data-dismiss="modal" (click)="Delete(i,kbase.DocumentDetails.Id)">Delete</button> </div> </div> </div> </div> </td> </tr> </ng-template>
方式二:用Angular变量动态绑定删除数据(更符合Angular风格)
只保留一个模态框,点击Remove按钮时先把当前行的索引和文档ID存入组件变量,再打开模态框,删除时直接使用这些变量。
步骤1:在组件TS中添加变量
// 存储当前要删除的行索引和文档ID currentDeleteIndex: number | null = null; currentDeleteId: number | null = null; // 打开删除模态框的方法 openDeleteModal(index: number, docId: number) { this.currentDeleteIndex = index; this.currentDeleteId = docId; // 调用原生Bootstrap模态框的打开方法(如果用的是Bootstrap) $('#exampleModalCenter').modal('show'); }
步骤2:修改HTML代码
<ng-template #tmplt> <tr *ngFor="let kbase of Colum; let i =index"> <!-- 省略其他列代码 --> <td> <!-- 点击按钮时调用自定义方法,传入当前行数据 --> <button class="btn btn-danger" type="button" (click)="openDeleteModal(i, kbase.DocumentDetails.Id)">Remove</button> <!-- 模态框保留一个,无需动态ID --> <div class="modal fade" id="exampleModalCenter" tabindex="-1" role="dialog" aria-labelledby="exampleModalCenterTitle" aria-hidden="true"> <div class="modal-dialog" role="document"> <div class="modal-content"> <!-- 省略模态框头部、内容代码 --> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button> <!-- 使用组件中存储的变量调用删除方法,添加非空断言确保值存在 --> <button type="button" class="btn btn-danger" data-dismiss="modal" (click)="Delete(currentDeleteIndex!, currentDeleteId!)">Delete</button> </div> </div> </div> </div> </td> </tr> </ng-template>
注意事项
- 方式一中要确保生成的ID唯一,避免和页面其他元素ID冲突;
- 方式二中如果你的项目使用了Angular专属的模态框组件(比如ng-bootstrap的NgbModal),可以替换掉原生的
$('#exampleModalCenter').modal('show'),用组件提供的API来打开模态框,会更优雅; - 方式二中可以在模板里添加判断,比如
[disabled]="!currentDeleteIndex && !currentDeleteId"来禁用删除按钮,直到有数据被选中。
内容的提问来源于stack exchange,提问作者Arun Kumar
相关产品推荐
相关产品推荐

