Angular表格展开行显示重复数据问题求助
解决Angular表格展开行共用数据的问题
我完全懂你遇到的糟心事——每次点不同的表格行展开详情,结果所有展开的行都显示最后一次点击那行的数据对吧?你猜的一点没错,问题根源就是共用了同一个全局的$scope.newObj对象,所有展开的行都绑定这个变量,每次点击都会覆盖它的值,自然所有行都会同步显示最新的那组数据。
问题分析
你的togglePerson方法里,每次把$scope.child[index]赋值给全局的$scope.newObj,而所有展开的<tr>都在绑定这个变量。不管你点哪一行,最后这个变量的值都会被最后一次点击的那项数据覆盖,所以所有展开行都会显示同一个内容。
解决方案
这里给你两种实用的解决思路,选适合你项目的就行:
方案一:给每个用户对象关联对应的详情数据
这种方式最直观,把每个用户的详情数据直接挂到对应的user对象上,这样每行的展开内容只绑定当前行的用户数据,不会互相干扰。
修改控制器代码:
'use strict'; angular.module('sbAdminApp') .controller('TreeTableCtrl', TreeTableCtrl); function TreeTableCtrl($scope, $http, factor) { $scope.nonCollapsedUser = []; var getUsers = function () { factor.getUse().then(function (response) { $scope.users = response.data; // 先拿到用户数据,再获取详情并关联 getUsersInfo(); }); }; getUsers(); var getUsersInfo = function () { factor.getChi().then(function (response) { var childData = response.data; // 假设用户数据和详情数据的下标一一对应,把详情绑定到每个user的child属性上 $scope.users.forEach(function(user, index) { user.child = childData[index]; }); }); }; $scope.togglePerson = function (index) { $scope.nonCollapsedUser.push(index); }; $scope.hidePerson = function (index) { // 简化删除逻辑,不用循环 var idx = $scope.nonCollapsedUser.indexOf(index); if (idx !== -1) { $scope.nonCollapsedUser.splice(idx, 1); } }; }
修改HTML代码,绑定当前用户的详情:
<div class="panel panel-default" style="background: #fcf8e3"> <div class="panel-body"> <table st-safe-src="leads" class="table table-hover"> <thead> <tr> <th>ID</th> <th>Name</th> <th>Last Name</th> </tr> </thead> <tbody ng-repeat="user in users track by $index"> <tr> <td>{{user.id}}</td> <td>{{user.name}}</td> <td>{{user.lastName}}</td> <td> <button ng-if="nonCollapsedUser.indexOf($index) == -1" class="btn" ng-click="togglePerson($index)"> <i class="fa fa-arrow-down"></i></button> <button ng-if="nonCollapsedUser.indexOf($index) !== -1" class="btn" ng-click="hidePerson($index)"><i class="fa fa-arrow-up"></i></button> </td> </tr> <tr ng-if="nonCollapsedUser.indexOf($index) !== -1"> <td>{{user.child.address}}</td> <td>{{user.child.mobNumb}}</td> </tr> </tbody> </table> </div> </div>
方案二:用对象存储每个展开行的独立数据
如果不想修改原有的user对象,可以创建一个专门的对象,用行下标作为key来存储对应行的详情数据,确保每个展开行绑定自己的专属数据。
修改控制器代码:
'use strict'; angular.module('sbAdminApp') .controller('TreeTableCtrl', TreeTableCtrl); function TreeTableCtrl($scope, $http, factor) { $scope.nonCollapsedUser = []; $scope.expandedData = {}; // 存储每个展开行的详情数据,key是行下标 var getUsers = function () { factor.getUse().then(function (response) { $scope.users = response.data; }); }; getUsers(); var getUsersInfo = function () { factor.getChi().then(function (response) { $scope.child = response.data; }); }; getUsersInfo(); $scope.togglePerson = function (index) { $scope.nonCollapsedUser.push(index); // 用下标作为key,存储当前行的详情 $scope.expandedData[index] = $scope.child[index]; }; $scope.hidePerson = function (index) { var idx = $scope.nonCollapsedUser.indexOf(index); if (idx !== -1) { $scope.nonCollapsedUser.splice(idx, 1); delete $scope.expandedData[index]; // 移除对应行的详情数据 } }; }
修改HTML代码:
<tr ng-if="nonCollapsedUser.indexOf($index) !== -1"> <td>{{expandedData[$index].address}}</td> <td>{{expandedData[$index].mobNumb}}</td> </tr>
额外小提示
如果你的用户数据和详情数据不是通过下标一一对应的(比如可能存在排序、过滤的情况),建议用共同的ID字段来匹配关联,比如用user.id去匹配child.id,这样数据关联会更准确,避免下标错位的问题。
内容的提问来源于stack exchange,提问作者Ivan Luketić
相关产品推荐
相关产品推荐

