页面加载时选中UI Grid行的实现及forEach报错解决
Hey there, let's break down why you're seeing this error and how to fix it so you can auto-select a row when your page loads.
What's causing the error?
That forEach is not a function message tells us that somewhere in UI Grid's code, it's trying to run forEach on a value that isn't an array. In your case, this is almost certainly because:
- Your
deviceDetailsdata source isn't initialized as an array when the grid registers its API, so$scope.deviceGrid.dataisundefinedor a non-array value. - Your data is loaded asynchronously (like from an API), and you're trying to select the row before the data has actually finished loading.
Step-by-step fixes
1. Initialize your data source first
Always start by initializing your bound data array to an empty array. This prevents UI Grid from trying to process an undefined value:
// At the top of your controller $scope.deviceDetails = [];
2. Only select the row after data is loaded
If your data comes from an async call (like $http or a service), you need to wait until the data is ready before trying to select a row. Using $timeout ensures the grid has finished rendering the new data before you attempt selection:
// Example: Async data fetch with $http $http.get('/your-api-endpoint/devices') .then(function(response) { $scope.deviceDetails = response.data; // Wait for the grid to process the new data $timeout(function() { // Only select if there's data to select if ($scope.deviceDetails.length > 0) { $scope.gridApi.selection.selectRow($scope.deviceDetails[0]); } }); });
3. Remove the unnecessary modifyRows call
Your line $scope.gridApi.grid.modifyRows($scope.deviceGrid.data); is likely contributing to the issue. modifyRows expects an array of UI Grid Row objects (not your raw data array), and you don't need it just to select a row. UI Grid automatically syncs with your deviceDetails array, so you can skip this line entirely.
4. Full working example
Here's a complete controller snippet putting it all together:
angular.module('yourApp').controller('YourController', function($scope, $http, $timeout) { // Initialize empty data array $scope.deviceDetails = []; $scope.deviceGrid = { data: 'deviceDetails', enableRowSelection: true, enableRowHeaderSelection: false, enableSelectAll: false, multiSelect: false, noUnselect: true, minRowsToShow: 10, onRegisterApi: function(gridApi) { $scope.gridApi = gridApi; // Optional: Watch for changes to deviceDetails to auto-select when data loads $scope.$watch('deviceDetails', function(newData) { if (newData && newData.length > 0) { $timeout(function() { $scope.gridApi.selection.selectRow(newData[0]); }); } }, true); // Deep watch to catch array content changes } }; // Simulate async data load (replace with your actual API call) $timeout(function() { $scope.deviceDetails = [ { id: 1, name: "Device Alpha", status: "Online" }, { id: 2, name: "Device Beta", status: "Offline" } ]; }, 1000); });
Key Notes
- The
$timeoutis crucial here because it waits for Angular's digest cycle to finish, giving UI Grid time to convert your raw data into its internal Row objects before you try to select one. - The deep
$watchensures that if your data updates later (not just on initial load), the grid will re-select the first row if needed.
内容的提问来源于stack exchange,提问作者Tharuka

