AngularJS实现按App名称分组的可展开表格需求求助
Got it, let's fix this grouping and expand/collapse functionality for your AngularJS table. Here's a step-by-step solution that fits your existing code:
1. Fix Data Fetching (Avoid Closure Issues & Improve Async Handling)
First, your current loop with $http.get has a closure problem with the i variable, and it's inefficient to fire requests one by one. Let's use $q.all to batch all requests and handle them together:
function DashboardTablesPageCtrl($scope, $http, $timeout, $q) { // Add $q dependency $scope.tableData = []; $scope.myFilter = ""; $scope.groupedData = []; // New variable for grouped data var req = { method: 'POST', url: 'https://'+ACCOUNTNAME+'.cloudant.com/_session', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data: 'name='+APIKEY+'&password='+APIPASSWORD, withCredentials: true }; $http(req).then(function(result){ // Grab data req = { method: 'GET', url: 'https://'+ACCOUNTNAME+'.cloudant.com/'+DATABASE+'/_all_docs', withCredentials: true }; $http(req).then(function(result){ var fetchPromises = []; // Collect all document fetch promises first angular.forEach(result.data.rows, function(row) { fetchPromises.push($http.get('https://'+ACCOUNTNAME+'.cloudant.com/'+DATABASE+'/'+row.id)); }); // Wait for all requests to complete $q.all(fetchPromises).then(function(responses) { angular.forEach(responses, function(response) { var data = response.data; angular.forEach(data.data[0].appDetails, function(appDetail) { angular.forEach(appDetail.appDescription, function(appDescription){ $scope.tableData.push(appDescription); }); }); }); }).catch(function() { console.log("Failed at grabbing data"); }); }, function(){ console.log("Failed at grabbing data"); }); }, function(){ console.log('Failed at authenticating'); }); // ... rest of the code goes here }
2. Add Grouping Logic & Expand/Collapse Function
Next, we'll watch for changes to tableData and group entries by appName, plus add a function to toggle expansion state:
// Add this inside your controller $scope.$watch('tableData', function(newData) { if (newData && newData.length > 0) { // Group data by appName const grouped = {}; angular.forEach(newData, function(item) { if (!grouped[item.appName]) { grouped[item.appName] = { appName: item.appName, isExpanded: false, // Track expansion state items: [] }; } grouped[item.appName].items.push(item); }); // Convert object to array for ng-repeat $scope.groupedData = Object.values(grouped); } }, true); // Deep watch to detect changes in array items // Toggle expand/collapse for a group $scope.toggleGroup = function(group) { group.isExpanded = !group.isExpanded; };
3. Update HTML Template for Grouped Rows
Modify your table <tbody> to render group headers first, then show/hide detail rows based on the group's expansion state:
<tbody> <!-- Group Header Rows (Click to expand/collapse) --> <tr ng-repeat="group in groupedData | filter: { items: myFilter }" ng-click="toggleGroup(group)" style="cursor: pointer; background-color: #f5f5f5;" > <td colspan="9"> <span>{{ group.appName }} ({{ group.items.length }} records)</span> <span style="float: right;">{{ group.isExpanded ? '▼' : '▶' }}</span> </td> </tr> <!-- Detail Rows (Show only when group is expanded) --> <tr ng-repeat="item in group.items | filter: myFilter" ng-show="group.isExpanded" > <td>{{ item.appName }}</td> <td>{{ item.GitTag }}</td> <td>{{ item.blocker }}</td> <td>{{ item.critical }}</td> <td>{{ item.major }}</td> <td>{{ item.minor }}</td> <td>{{ item.UnitTestsTotal }}</td> <td>{{ item.FailedTests }}</td> <td>{{ item.CodeCoverage }}</td> </tr> </tbody>
4. Notes on Filtering
The filter: { items: myFilter } on the group rows ensures that only groups with matching detail items are shown. The detail rows also use the same filter, so only matching entries within an expanded group will display.
Key Improvements:
- Fixed async data fetching to avoid race conditions and closure bugs
- Added proper grouping by
appNamewith expansion state tracking - Clean, clickable group headers with visual indicators (arrow icons)
- Filter compatibility for both groups and detail rows
内容的提问来源于stack exchange,提问作者devops_engineer

