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

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ć

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:21:34