You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

嵌套ng-repeat+Bootstrap折叠面板:$index与ng-init异常排查

解决Bootstrap手风琴结合Angular多层ng-repeat的ID冲突问题

你碰到的问题根源很明确:手风琴面板的ID和触发链接的href属性重复了,导致Bootstrap的折叠组件只能识别第一个匹配的ID,第二个省份下的面板自然就无法正常展开了。

问题分析

看你原来的代码,地区面板的ID是collapse-1-1{{subdivIndex2}},其中subdivIndex2只是当前省份内部地区的$index。比如第一个省份的第一个地区$index是0,第二个省份的第一个地区$index也是0,这就导致两个地区面板的ID完全一样(都是collapse-1-10)。而Bootstrap的折叠功能是依赖全局唯一ID来绑定触发元素和面板的,重复ID会让组件“迷路”,只能响应第一个匹配的元素。

解决方案

要解决这个问题,我们需要把**父层级的索引(也就是省份的索引)**也加入到子面板的ID中,确保每个面板的ID在整个页面是唯一的。同时,还要调整data-parent属性的指向,保证每个省份下的地区手风琴是独立的容器。

修改后的完整代码

HTML部分

<div class="subdiv-wrapper">
  <!-- 省份层级手风琴 -->
  <div class="panel-group" id="province-accordion" ng-repeat="admin in subdivisions" ng-init="provinceIndex = $index">
    <div class="panel panel-default">
      <div class="panel-heading">
        <h4 class="panel-title">
          <a data-toggle="collapse" data-parent="#province-accordion" href="#province-collapse-{{provinceIndex}}">
            <span class="span-left">{{ admin.province[0].name }}</span>
            <span class="span-right">{{ admin.province[0].population }}</span>
          </a>
        </h4>
      </div>
      <div id="province-collapse-{{provinceIndex}}" class="panel-collapse collapse">
        <div class="panel-body">
          <h3>districts</h3>
          <!-- 地区层级手风琴,每个省份对应独立的容器 -->
          <div class="panel-group" id="district-accordion-{{provinceIndex}}">
            <div class="panel panel-default" ng-repeat="district in admin.district" ng-init="districtIndex = $index">
              <div class="panel-heading">
                <h4 class="panel-title">
                  <a data-toggle="collapse" data-parent="#district-accordion-{{provinceIndex}}" href="#district-collapse-{{provinceIndex}}-{{districtIndex}}">
                    <span class="span-left">{{ district.name }}</span>
                    <span class="span-right">{{ district.population }}</span>
                  </a>
                </h4>
              </div>
              <div id="district-collapse-{{provinceIndex}}-{{districtIndex}}" class="panel-collapse collapse">
                <div class="panel-body">
                  <div ng-repeat="commune in district.commune">
                    <span class="span-left">{{ commune.name }}</span>
                    <span class="span-right">{{ commune.population }}</span>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

JavaScript控制器数据(结构优化版,可选)

$scope.subdivisions = [
  // 省份:Adrar
  {
    "province": {"name":"Adrar","population":"123"}, // 简化为单个对象,因为每个条目对应一个省份
    "district": [
      {"name":"Adrar","population":"123","commune":[{"name":"Adrar","population":"123"},{"name":"Bouda","population":"123"},{"name":"Ouled Ahmed Timmi","population":"123"}]},
      {"name":"Aoulef","population":"123","commune":[{"name":"Akabli","population":"123"},{"name":"Aoulef","population":"123"},{"name":"Timokten","population":"123"}]},
      {"name":"Aougrout","population":"123","commune":[{"name":"Aougrout","population":"123"},{"name":"Deldoul","population":"123"},{"name":"Metarfa","population":"123"}]}
    ]
  },
  // 省份:Algiers
  {
    "province": {"name":"Algiers","population":"123"},
    "district": [
      {"name":"Bab El Oued","population":"123","commune":[{"name":"Bab El Oued","population":"123"},{"name":"Casbah","population":"123"},{"name":"Bains Romains","population":"123"}]},
      {"name":"Baraki","population":"123","commune":[{"name":"Baraki","population":"123"},{"name":"Les Eucalyptus","population":"123"},{"name":"Sidi Moussa","population":"123"}]},
      {"name":"Bir Mourad Raïs","population":"123","commune":[{"name":"Bir Mourad Raïs","population":"123"},{"name":"Hydra","population":"123"},{"name":"Saoula","population":"123"}]}
    ]
  }
];

关键修改点说明

  1. 唯一ID生成:

    • 省份面板ID:province-collapse-{{provinceIndex}},结合省份的索引确保全局唯一
    • 地区面板ID:district-collapse-{{provinceIndex}}-{{districtIndex}},同时使用省份索引和地区索引,彻底避免ID重复
  2. 独立手风琴容器:

    • 每个省份下的地区手风琴容器ID是district-accordion-{{provinceIndex}},搭配data-parent="#district-accordion-{{provinceIndex}}",保证每个省份内的地区面板只会在自己的容器内工作,不会和其他省份的面板互相干扰
  3. 数据结构优化(可选):

    • 原来的province是数组,但每个条目只对应一个省份,所以简化为单个对象,这样HTML里可以直接用admin.province.name而不是admin.province[0].name,代码更简洁

这样修改后,每个层级的面板都能独立正常开闭,不会再出现第二个省份面板失效的问题了。

内容的提问来源于stack exchange,提问作者Gryffin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:16:11