我使用ng-resource从我的服务器获取数据,然后将数据放入这样的表格中:
<div ng-form name="grid">
<button type="submit" data-ng-disabled="grid.$pristine">Save</button>
<div class="no-margin">
<table width="100%" cellspacing="0" class="form table">
<thead class="table-header">
<tr>
<th>ID</th>
<th>Title</th>
</tr>
</thead>
<tbody class="grid">
<tr data-ng-repeat="row in grid.data">
<td>{{ row.contentId }}</td>
<td><input type="text" ng-model="row.title" /></td>
</tr>
</tbody>
</table>
</div>
</div>
有没有办法让我可以点击“提交”按钮检查网格中是否有更改的行,然后以行作为参数调用putEntity(row)
函数?
答案 0 :(得分:12)
你可以通过几种方式做到这一点,并记住每个NgModelController都有一个$ dirty标志,可用于检查输入是否已更改。但我想说最简单的方法就是这样做:
编辑为HTML:
<input type="text" ng-model="row.title" ng-change="row.changed=true" />
<button ng-click="save()">Save</button>
在JS中:
$scope.save = function () {
// iterate through the collection and call putEntity for changed rows
var data = $scope.grid.data;
for (var i = 0, len = data.length; i < len; i++) {
if (data[i].changed) {
putEntity(data[i]);
}
}
}
答案 1 :(得分:3)
Here's something that could work.它是以第一条评论中的JSFiddle为基础构建的。
首先,我将data-ng-disabled
属性更改为changes.length <= 0
并将$scope.changes = []
添加到控制器。
$scope.changes = [];
然后我在$scope.data
$scope.$watch('data', function(newVal, oldVal){
for(var i = 0; i < oldVal.length; i++){
if(!angular.equals(oldVal[i], newVal[i])){
console.log('changed: ' + oldVal[i].name + ' to ' + newVal[i].name);
var indexOfOld = $scope.indexOfExisting($scope.changes, 'contentId', newVal[i].contentId);
if(indexOfOld >= 0){
$scope.changes.splice(indexOfOld, 1);
}
$scope.changes.push(newVal[i]);
}
}
}, true); // true makes sure it's a deep watch on $scope.data
基本上,它会遍历数组并使用angular.equals检查是否有任何更改。如果对象已更改,则会检查它是否已存在于$scope.changes
中。如果确实如此,则将其删除。之后newVal[i]
被推送到$scope.changes
$scope.indexOfExisting
取自this SO question
$scope.indexOfExisting = function (array, attr, value) {
for(var i = 0; i < array.length; i += 1) {
if(array[i][attr] === value) {
return i;
}
}
};
最后我让$scope.checkChange()
看起来像这样
$scope.checkChange = function(){
for(var i = 0; i < $scope.changes.length; i++){
console.log($scope.changes[i].name);
//putEntity($scope.changes[i])
}
$scope.changes = [];
};
这将使您能够仅提交更改的行。
答案 2 :(得分:2)
我决定这样做:
这是我获取数据然后复制它的地方:
getContents: function ($scope, entityType, action, subjectId, contentTypeId, contentStatusId) {
entityService.getContents(entityType, action, subjectId, contentTypeId, contentStatusId)
.then(function (result) {
$scope.grid.data = result;
$scope.grid.backup = angular.copy(result);
$scope.grid.newButtonEnabled = true;
}, function (result) {
alert("Error: No data returned");
$scope.grid.newButtonEnabled = false;
});
},
然后,在保存时,我使用angular.equals与备份进行比较:
$scope.saveData = function () {
var data = $scope.grid.data;
for (var i = 0, len = $scope.grid.data.length; i < len; i++) {
if (!angular.equals($scope.grid.data[i], $scope.grid.backup[i])) {
var rowData = $scope.grid.data[i]
var idColumn = $scope.entityType.toLowerCase() + 'Id';
var entityId = rowData[idColumn];
entityService.putEntity($scope.entityType, entityId, $scope.grid.data[i])
.then(function (result) {
angular.copy(result, $scope.grid.data[i]);
angular.copy(result, $scope.grid.backup[i]);
}, function (result) {
alert("Error: " + result);
})
}
}
$scope.grid.newButtonEnabled = true;
$scope.grid.saveButtonEnabled = false;
$scope.$broadcast('tableDataSetPristine');
}
答案 3 :(得分:2)
我为自己做了一些非常相似的事情,并且我使用了不同的方式,我决定直接将所有ng-model绑定到数据,如果我需要检查每一行,我可以使用索引,但我可以还决定将整个数据发送到服务器
然后,我只需要观察对每个索引所做的所有更改(即使使用大数据,我只需要添加/删除整数)并将它们存储在数组中
完成后,我可以点击提交按钮,它会在我触摸的每个索引上循环,检查内容是否与原始内容完全不同,然后我可以随心所欲地做任何事情(如调用一个putEntity函数,如果我有一个)
我根据您的HTML代码制作了一个小提琴,使用它比使用代码的复制/粘贴更容易:http://jsfiddle.net/DotDotDot/nNwqr/1/
HTML中的主要变化是此部分,将模型绑定到数据并添加更改侦听器
<td><input type="text" ng-model="data[$index].title" ng-change="notifyChange($index)"/></td>
我认为javascript部分是可以理解的,我在修改数据时记录索引,然后,当我点击提交按钮时,它可以根据记录的索引仅在修改的行上调用正确的函数