Angular 2按钮点击显示详情问题:如何实现对应行展开?
问题原因分析
你遇到的核心问题很明确:所有折叠面板的id都是同一个值demo。HTML要求页面内的id必须唯一,所以不管点击哪一行的按钮,浏览器只会找到第一个匹配#demo的元素展开,这就是详情总是显示在第一行的原因。
解决方案
我给你两种可行的修复方案,从基础修复到更优的Angular风格实现:
方案1:基础修复(保留原生Bootstrap折叠)
通过给每个折叠元素生成唯一id来解决冲突,推荐使用*ngFor的索引或者数据的唯一标识(比如data.Name,前提是它不重复):
用索引实现的代码示例
<tr *ngFor="let data of datas | search:'Name':query; let i = index"> <td> <button type="button" class="btn btn-info" data-toggle="collapse" [attr.data-target]="'#demo-' + i" (click)="calculateValue(data.Name, data.value)"> {{data.Name}} </button> </td> <td>{{data.LastValue | number : '1.2-8'}}</td> <td>{{data.High | number : '1.2-8'}}</td> </tr> <!-- 折叠行单独放在外面,用colspan占满整行,保证布局正确 --> <tr id="demo-{{i}}" class="collapse"> <td colspan="3">Price: {{value | number : '1.2-5'}}</td> </tr>
关键修改点
- 给按钮的
data-target绑定动态值,用索引i生成唯一的#demo-i - 对应的折叠行
id设为demo-{{i}},确保每个行的标识唯一 - 折叠行的
td添加colspan="3"(对应原表格的列数),避免布局错乱
方案2:更优的Angular风格实现(使用ng-bootstrap)
直接用原生Bootstrap的data-toggle容易和Angular的变更检测机制冲突,更推荐使用ng-bootstrap(专门为Angular封装的Bootstrap组件库),完全用Angular变量控制折叠状态,代码更清晰:
步骤1:安装并导入ng-bootstrap
npm install @ng-bootstrap/ng-bootstrap
在你的模块中导入组件:
import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap'; @NgModule({ imports: [NgbCollapseModule, /* 其他模块 */] }) export class YourComponentModule { }
步骤2:修改模板和组件逻辑
组件类中添加状态数组:
import { Component, OnInit } from '@angular/core'; @Component({ // 组件元数据 }) export class YourComponent implements OnInit { isCollapsed: boolean[] = []; datas: any[] = []; // 你的数据数组 value: number = 0; ngOnInit() { // 初始化折叠状态,默认全部折叠 this.isCollapsed = new Array(this.datas.length).fill(true); } calculateValue(name: string, val: number) { // 你的计算逻辑 this.value = val * 1.5; // 示例计算 } }
模板代码:
<tr *ngFor="let data of datas | search:'Name':query; let i = index"> <td> <button type="button" class="btn btn-info" (click)="isCollapsed[i] = !isCollapsed[i]; calculateValue(data.Name, data.value)"> {{data.Name}} </button> </td> <td>{{data.LastValue | number : '1.2-8'}}</td> <td>{{data.High | number : '1.2-8'}}</td> </tr> <tr [ngbCollapse]="isCollapsed[i]"> <td colspan="3">Price: {{value | number : '1.2-5'}}</td> </tr>
方案优势
- 不需要依赖HTML的
id,完全通过Angular变量控制状态,避免了id冲突问题 - 更符合Angular的组件化开发思想,和框架的变更检测机制兼容更好
- 代码逻辑更直观,维护成本更低
内容的提问来源于stack exchange,提问作者SUBHASIS MONDAL
相关产品推荐
相关产品推荐

