AG-GRID与AngularJS:如何通过外部表单同步编辑数据
解决外部表单编辑后AG-GRID数据不更新的问题
我来帮你搞定这个问题!你遇到的AG-GRID不更新的情况,主要是几个小问题叠加导致的,咱们一步步来修复:
问题根源分析
- Service中未定义持久化的
Current对象:你的Service里直接使用Current.Data,但Current变量根本没声明,导致无法正确维护编辑行的引用。 - 未在表单提交后通知AG-GRID刷新:即使修改了数据,AG-GRID可能没感知到变化;而且之前调用
refreshCells()的时机或参数不对,导致无效。 - 可能未正确引用原数组中的行对象:如果编辑的不是原
rowData数组里的对象引用,修改后原数据根本没变化,刷新自然没用。
具体修复步骤
1. 修复Service,正确维护编辑行引用
首先修改你的Service,添加持久化的Current对象,确保编辑的是原数组的行引用:
GDI_App.factory('Service', function($http, $q, $timeout, $mdDialog, $resource, $window) { // 声明持久化的Current对象,用来保存当前编辑的行 var Current = {}; return{ get_data: function(){ var example_data = [ { "Data1": "123123", "Data2": "15437" }, { "Data1": "432234", "Data2": "146" }, { "Data1": "45654", "Data2": "3534" }, { "Data1": "76587", "Data2": "78978" }, { "Data1": "2342", "Data2": "5345878" }, { "Data1": "178", "Data2": "34534" }, { "Data1": "173838", "Data2": "354534" }, ]; return example_data }, current_incident: function(data){ // 传入data时保存引用,否则返回当前编辑的行 if(data){ Current.Data = data; } return Current.Data; }, // 可选:如果需要更新原数组中的对应项(比如后端返回新数据) update_row: function(updatedRow){ var allData = this.get_data(); var index = allData.findIndex(item => item.Data1 === updatedRow.Data1); // 假设Data1是唯一标识 if(index !== -1){ allData[index] = updatedRow; } } } });
2. 修改表单控制器,提交成功后通知刷新
在表单提交成功后,通过AngularJS的事件广播通知主页面刷新AG-GRID,同时处理HTTP请求的Promise:
GDI_App.controller('Form_Controller', function ($scope, $http, $filter, $timeout, $mdDialog, $q, $resource, $interval, $mdSidenav, Service, $state) { // 获取当前编辑的行(直接引用原数组中的对象) $scope.Current = { Data: Service.current_incident() }; $scope.Submit = function(){ $http({ method: 'POST', url: REST_URL, processData: false, contentType: "application/json;odata=verbose", headers: HEADER_DATA, data: $scope.Current.Data }).then(function(response){ // 提交成功后返回主页面 $state.go('main'); // 替换成你的主页面state名称 // 广播刷新事件,通知主页面的AG-GRID更新 $scope.$broadcast('refreshAGGrid'); // 如果后端返回了更新后的数据,调用Service方法更新原数组 // Service.update_row(response.data); }).catch(function(error){ console.error('提交失败:', error); }); }; });
3. 主控制器监听刷新事件,正确触发AG-GRID更新
修改主控制器,保存AG-GRID的API引用,监听刷新事件并正确调用刷新方法:
App.controller('Main_Controller', function ($scope, $http, $filter, $timeout, $mdDialog, $q, $resource, $interval, $mdSidenav, $state, Service) { var Buttons = function(params) { return '<md-button class="md-icon-button" aria-label="Edit" ng-click="Edit(data)"> <md-icon class="material-icons">mode_edit</md-icon> </md-button>'; } var columnDefs = [ { cellRenderer: Buttons, width: 165 }, { headerName: "Data1", field: "Data1"}, { headerName: "Data2", field: "Data2"}, ]; // 把rowData保存到$scope,方便后续更新 $scope.rowData = Service.get_data(); $scope.gridOptions_incident = { columnDefs: columnDefs, domLayout: 'autoHeight', enableFilter: true, enableColResize: true, enableSorting: true, pagination: true, paginationPageSize:25, animateRows: true, headerHeight: headerHeight, rowHeight:rowHeight, angularCompileRows : true, enableCellChangeFlash: true, debug: true, rowData: $scope.rowData, // 网格就绪时保存API引用 onGridReady: function(params){ $scope.gridApi = params.api; } }; $scope.Edit = function(data){ Service.current_incident(data); $state.go('OPEN_ExternalForm'); }; // 监听来自表单的刷新事件 $scope.$on('refreshAGGrid', function(){ if($scope.gridApi){ // 强制刷新所有单元格,确保AG-GRID感知到数据变化 $scope.gridApi.refreshCells({ force: true, columns: ['Data1', 'Data2'] // 可选:指定要刷新的列,提升性能 }); // 如果是从后端重新获取了数据,替换成下面的代码: // $scope.rowData = Service.get_data(); // $scope.gridApi.setRowData($scope.rowData); } }); // 可选:监听路由回到主页面时自动刷新 $scope.$on('$stateChangeSuccess', function(event, toState){ if(toState.name === 'main'){ // 替换成你的主页面state名称 if($scope.gridApi){ $scope.gridApi.refreshCells({force: true}); } } }); });
为什么之前的refreshCells()没用?
- 你可能在AG-GRID的API未初始化完成时就调用了它,通过
onGridReady保存API引用可以解决这个问题。 - 没有传递
{force: true}参数,AG-GRID默认会检查数据是否真的变化,有时候引用类型的属性变化可能没被检测到,强制刷新就能解决。 - 之前Service里的
Current未定义,导致你编辑的不是原数组的行对象,原rowData根本没变化,刷新自然看不到效果。
内容的提问来源于stack exchange,提问作者Daniel Ellison
相关产品推荐
相关产品推荐

