AngularJS中团队子行(航班信息)无法正常显示问题求助
看起来你遇到的核心问题是AngularJS作用域变量的作用范围导致的,我帮你拆解下问题原因和解决方案:
问题根源分析
你当前的代码里,团队行的ng-repeat="(teamId, group) in groupedFlights"会创建一个局部作用域,teamId这个变量只在这个<tr>的作用域内有效。而你的航班行、无航班提示行是写在这个ng-repeat的<tr>外面的,这部分代码根本访问不到teamId变量——也就是说expandedTeams[teamId]里的teamId是undefined,所以ng-if永远不会成立,子行自然不会显示。
另外,你在toggleFlights里用$scope.groupedFlights.find(g => g.team.id === teamId)来查找分组,这里也可能有隐患:如果groupedFlights是一个对象(不是数组),find方法是不能直接用的(对象没有find方法),而且如果对象的键teamId和group.team.id不匹配的话,也会找不到数据,导致flights[teamId]为空。
解决方案
1. 用ng-repeat-start/ng-repeat-end统一作用域
把团队行、航班行、无航班提示行都包裹在同一个ng-repeat作用域里,这样teamId就能被所有子元素访问到。修改HTML部分如下:
<table class="table table-hover"> <thead> <tr> <th>Team Name</th> <th>City</th> <th>State</th> </tr> </thead> <tbody> <!-- 用ng-repeat-start标记循环的开始 --> <tr ng-repeat-start="(teamId, group) in groupedFlights"> <td> <button class="btn btn-link" ng-click="toggleFlights(teamId, group)"> <span ng-if="!expandedTeams[teamId]">▶</span> <span ng-if="expandedTeams[teamId]">▼</span> </button> {{ group.team.name }} </td> <td>{{ group.team.city }}</td> <td>{{ group.team.stateProvince }}</td> <td>Flights: {{group.flights|json}}</td> </tr> <!-- Flights Section - 现在和团队行在同一个ng-repeat作用域下,能访问teamId --> <tr ng-if="expandedTeams[teamId]" ng-repeat="flight in flights[teamId]"> <td style="padding-left: 40px;"> <b>Flight #:</b> {{ flight.flightNumber }} </td> <td> <b>Departure:</b> {{ flight.departureCity }} at {{ flight.departureTime }} </td> <td> <b>Arrival:</b> {{ flight.arrivalCity }} at {{ flight.arrivalTime }} </td> </tr> <!-- No Flights Message --> <tr ng-if="expandedTeams[teamId] && (!flights[teamId] || flights[teamId].length === 0)"> <td colspan="3" style="padding-left: 40px;"> No flights available for this team. </td> </tr> <!-- 用ng-repeat-end标记循环的结束 --> <tr ng-repeat-end></tr> </tbody> </table>
2. 优化toggleFlights函数,避免查找错误
直接把当前循环的group对象传入函数,不需要再通过find查找,这样更准确也更高效:
$scope.expandedTeams = {}; // Tracks expanded states by team ID $scope.flights = {}; // Cache flights by team ID $scope.toggleFlights = function (teamId, group) { // 直接切换展开状态 $scope.expandedTeams[teamId] = !$scope.expandedTeams[teamId]; // 如果是展开状态且未缓存航班,直接用当前group的flights赋值 if ($scope.expandedTeams[teamId] && !$scope.flights[teamId]) { $scope.flights[teamId] = group.flights || []; } };
3. 调用函数时传入group对象
修改团队行里的按钮点击事件,把当前的group传进去:
<button class="btn btn-link" ng-click="toggleFlights(teamId, group)">
为什么之前的{{group.flights|json}}能显示?
因为这行代码在团队行的ng-repeat作用域内,能直接访问当前group对象的flights属性,所以数据能正常渲染——这也说明你的航班数据本身是没问题的,只是作用域和变量引用的问题导致子行没显示。
备注:内容来源于stack exchange,提问作者charan

