AngularJS从数据对象添加表格行问题:push方法添加空行失效求助
解决AngularJS动态表格添加空行的问题(适配带数字键的API数据结构)
我明白你遇到的问题了——API返回的JSON结构有点特殊,不是直接的客户数组,而是数组包裹着一个以数字字符串为键的对象,直接用array.push肯定不生效,因为你搞错了要操作的目标结构。咱们一步步来解决:
问题根源分析
你的$scope.personalDetails是一个数组,但数组里只有1个元素:这个元素是个对象,每个客户信息是这个对象的属性(键是"1"、"2")。之前用push是往personalDetails数组里加新对象,而不是往这个内部的客户对象里加新的键值对,所以视图根本不会渲染新行。
解决方案:修改addNew函数,适配API数据结构
我们需要先找到当前客户对象里的最大数字键,然后生成下一个键,再给这个对象添加一个空的客户条目,结构和现有条目一致:
var app = angular.module("myapp", []); app.controller("ListController", ['$scope', function($scope) { $scope.personalDetails = [ { "1": { "name": "EZ-Catering", "name_label": "EZ-Catering", "address": "234 W. 11th St.\r\nBloomington IN 23484", "address_label": "234 W. 11th St.\r\nBloomington IN 23484", "contractDate_label": "2016-05-31", "contractDate": "2016-05-31 00:00:00", "currentClient": "1", "currentClient_label":"true" }, "2": { "name": "Smithee Lawn Service", "name_label": "Smithee Lawn Service", "address": "555 Main St.\r\nEvansville IN 46234", "address_label": "555 Main St.\r\nEvansville IN 46234", "contractDate_label": "2016-05-08", "contractDate": "2016-05-08 00:00:00", "currentClient": "0", "currentClient_label":"false" } } ]; // 修复后的添加空行函数 $scope.addNew = function(){ // 获取内部的客户对象 const clientsObj = $scope.personalDetails[0]; // 提取所有数字键,转成数字后找到最大值 const keys = Object.keys(clientsObj).map(key => parseInt(key)); const maxKey = keys.length > 0 ? Math.max(...keys) : 0; // 生成新键(最大值+1,转成字符串) const newKey = (maxKey + 1).toString(); // 添加空的客户条目,结构和现有一致 clientsObj[newKey] = { "name": "", "name_label": "", "address": "", "address_label": "", "contractDate_label": "", "contractDate": "", "currentClient": "0", "currentClient_label":"false" }; }; $scope.remove = function() { $scope.selectedAll = false; // 注意:这里也要适配结构,遍历的是客户对象的属性 const clientsObj = $scope.personalDetails[0]; const newClientsObj = {}; angular.forEach(clientsObj, function(detail, key){ if(!detail.selected){ newClientsObj[key] = detail; } }); $scope.personalDetails[0] = newClientsObj; }; $scope.checkAll = function () { if (!$scope.selectedAll) { $scope.selectedAll = true; } else { $scope.selectedAll = false; } // 遍历客户对象的属性 angular.forEach($scope.personalDetails[0], function(detail) { detail.selected = $scope.selectedAll; }); }; }]);
配套视图修改(关键!)
你的HTML视图里,ng-repeat要遍历客户对象的键值对,而不是数组。示例代码如下:
<div ng-app="myapp" ng-controller="ListController"> <button ng-click="addNew()">添加空行</button> <button ng-click="remove()">删除选中行</button> <input type="checkbox" ng-model="selectedAll" ng-click="checkAll()"> 全选 <table> <thead> <tr> <th>选择</th> <th>名称</th> <th>地址</th> <th>合同日期</th> <th>当前客户</th> </tr> </thead> <tbody> <!-- 遍历客户对象的键和值 --> <tr ng-repeat="(key, detail) in personalDetails[0]"> <td><input type="checkbox" ng-model="detail.selected"></td> <td><input type="text" ng-model="detail.name"></td> <td><textarea ng-model="detail.address"></textarea></td> <td><input type="date" ng-model="detail.contractDate_label"></td> <td><input type="checkbox" ng-model="detail.currentClient_label" ng-true-value="'true'" ng-false-value="'false'"></td> </tr> </tbody> </table> </div>
额外说明
- 我还同步修改了
remove和checkAll函数,确保它们也适配这个特殊的数据结构,不然删除和全选功能也会失效。 - 如果API返回的数组可能有多个元素(虽然当前只有1个),你需要根据实际情况调整,但从你的示例来看,应该是数组里固定只有一个客户对象。
内容的提问来源于stack exchange,提问作者user1994739
相关产品推荐
相关产品推荐

