使用*ngFor动态构建Accordion时如何实现单条目独立展开?
解决方案
你的推测是正确的,所有折叠面板的ID、触发目标属性全部硬编码为相同值,Bootstrap的折叠组件会匹配所有对应ID的元素,因此会出现点击后所有面板同时展开/收起的问题。以下是两种可用的修改方案:
方案1:使用task自带的唯一ID(推荐)
如果你的task对象本身存在id这类唯一标识字段,直接用该字段拼接动态ID即可,修改后代码如下:
<div class="accordion" id="accordionExample"> <div *ngFor="let task of tasks" class="accordion-item"> <!-- 动态生成header的唯一ID --> <h2 class="accordion-header" [id]="'heading-' + task.id"> <button class="accordion-button" type="button" data-bs-toggle="collapse" <!-- 动态绑定对应折叠面板的ID --> [attr.data-bs-target]="'#collapse-' + task.id" aria-expanded="true" <!-- 关联对应折叠面板ID --> [attr.aria-controls]="'collapse-' + task.id" > {{task.name}} </button> </h2> <!-- 动态生成折叠面板的唯一ID --> <div [id]="'collapse-' + task.id" class="accordion-collapse collapse" <!-- 关联对应header的ID --> [attr.aria-labelledby]="'heading-' + task.id" data-bs-parent="#accordionExample" > <div class="accordion-body"> {{task.description}} </div> </div> </div> </div>
方案2:使用ngFor的索引生成唯一ID
如果task没有专属的唯一ID字段,可以用*ngFor暴露的索引变量拼接ID:
<div class="accordion" id="accordionExample"> <!-- 声明索引变量i --> <div *ngFor="let task of tasks; let i = index" class="accordion-item"> <h2 class="accordion-header" [id]="'heading-' + i"> <button class="accordion-button" type="button" data-bs-toggle="collapse" [attr.data-bs-target]="'#collapse-' + i" aria-expanded="true" [attr.aria-controls]="'collapse-' + i" > {{task.name}} </button> </h2> <div [id]="'collapse-' + i" class="accordion-collapse collapse" [attr.aria-labelledby]="'heading-' + i" data-bs-parent="#accordionExample" <!-- 如果需要默认展开第一个面板,保留下方的类绑定即可 --> [class.show]="i === 0" > <div class="accordion-body"> {{task.description}} </div> </div> </div> </div>
关键修改说明
- 所有ID属性改为使用Angular属性绑定动态生成,保证每个面板的ID唯一不重复
- 绑定
data-bs-target、aria-*这类自定义属性时需要加attr.前缀,否则Angular无法识别为原生DOM属性 - 移除了硬编码的
show类,避免所有面板默认展开,如有需要可通过索引判断为指定面板添加该类
内容的提问来源于stack exchange,提问作者Ron
相关产品推荐
相关产品推荐

