我花了一些时间为 ng-grid 2.x 整理了这些内容。我仍然有一个问题,必须单击两次才能编辑一行,但我认为这是一个引导问题,而不是 ngGrid 问题,它不会发生在我的示例代码中(它还没有引导)。
我还在 ui-grid 3.0 的教程中实现了类似的逻辑,它仍然是测试版,但很快就会成为首选版本。这可以在以下位置找到:http ://technpol.wordpress.com/2014/08/23/upgrading-to-ng-grid-3-0-ui-grid/ ,并为此功能提供了更简单、更清洁的 api .
对于 2.x 版本,为了说明所有内容,我创建了一个正在运行的 plunker,它有一个带有下拉列表和输入字段的可编辑网格,使用 ngBlur 指令,并使用 $timeout 来避免重复保存更新:http ://plnkr.co/edit/VABAEu?p=preview
代码的基本内容是:
var app = angular.module('plunker', ["ngGrid"]);
app.controller('MainCtrl', function($scope, $timeout, StatusesConstant) {
$scope.statuses = StatusesConstant;
$scope.cellInputEditableTemplate = '<input ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" ng-blur="updateEntity(row)" />';
$scope.cellSelectEditableTemplate = '<select ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" ng-options="id as name for (id, name) in statuses" ng-blur="updateEntity(row)" />';
$scope.list = [
{ name: 'Fred', age: 45, status: 1 },
{ name: 'Julie', age: 29, status: 2 },
{ name: 'John', age: 67, status: 1 }
];
$scope.gridOptions = {
data: 'list',
enableRowSelection: false,
enableCellEditOnFocus: true,
multiSelect: false,
columnDefs: [
{ field: 'name', displayName: 'Name', enableCellEditOnFocus: true,
editableCellTemplate: $scope.cellInputEditableTemplate },
{ field: 'age', displayName: 'Age', enableCellEdit: false },
{ field: 'status', displayName: 'Status', enableCellEditOnFocus: true,
editableCellTemplate: $scope.cellSelectEditableTemplate,
cellFilter: 'mapStatus'}
]
};
$scope.updateEntity = function(row) {
if(!$scope.save) {
$scope.save = { promise: null, pending: false, row: null };
}
$scope.save.row = row.rowIndex;
if(!$scope.save.pending) {
$scope.save.pending = true;
$scope.save.promise = $timeout(function(){
// $scope.list[$scope.save.row].$update();
console.log("Here you'd save your record to the server, we're updating row: "
+ $scope.save.row + " to be: "
+ $scope.list[$scope.save.row].name + ","
+ $scope.list[$scope.save.row].age + ","
+ $scope.list[$scope.save.row].status);
$scope.save.pending = false;
}, 500);
}
};
})
.directive('ngBlur', function () {
return function (scope, elem, attrs) {
elem.bind('blur', function () {
scope.$apply(attrs.ngBlur);
});
};
})
.filter('mapStatus', function( StatusesConstant ) {
return function(input) {
if (StatusesConstant[input]) {
return StatusesConstant[input];
} else {
return 'unknown';
}
};
})
.factory( 'StatusesConstant', function() {
return {
1: 'active',
2: 'inactive'
};
});
当你运行这个 plunker 并且失去焦点触发时,你应该在控制台上看到更新触发器触发。
我还在 plunker 中包含了一个 README.md,其中包含对给我带来困难的事情的一些想法,在此处复制。
这里的功能是我有一个人员列表,这些人有姓名、年龄和状态。与我们在真实应用中可能执行的操作一致,状态是一个代码,我们想要显示解码。因此,我们有一个状态码列表(在真实的应用程序中可能来自数据库),我们有一个过滤器将代码映射到解码。
我们想要的是两件事。我们希望能够在输入框中编辑名称,并在下拉列表中编辑状态。
评论我在这个 plunk 上学到的东西。
在 gridOptions 级别,有 enableCellEditOnFocus 和 enableCellEdit。不要同时启用,你需要选择。onFocus 表示单击,CellEdit 表示双击。如果您同时启用两者,那么您会在您不想编辑的网格位上出现意外行为
在 columnDefs 级别,您有相同的选项。但是这一次您需要同时设置 CellEdit 和 onFocus,并且您需要在您不想编辑的任何单元格上将 cellEdit 设置为 false - 这不是默认设置
文档说您的可编辑单元格模板可以是:
<input ng-class="'colt' + col.index" ng-input="COL_FIELD" />
实际上它需要是:
<input ng-class="'colt' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" />
为了在我们失去焦点时触发保存事件,我们创建了一个模糊指令,我在 stackoverflow 中找到了它的逻辑:AngularJS 和 ng-grid - 在单元格更改后自动将数据保存到服务器
这也意味着将每个可编辑单元格模板更改为调用 ng-blur,您可以在可编辑单元格模板的末尾看到
当我们离开现场时(至少在 Chrome 中),我们得到了两个模糊事件,所以我们使用了一个计时器,以便只处理其中一个。丑陋,但它的工作原理。
我还创建了一篇博客文章,对这段代码进行了更彻底的演练:http: //technpol.wordpress.com/2013/12/06/editable-nggrid-with-both-dropdowns-and-selects/