我在gridController as gc
中有一个ng重复,用于填充引导表:
<div ng-repeat="(id, task) in gc.modelFilter(model.getModelAsDict())">
<div ng-show="model.getTask(id).edit_active" class="row">
<div class="col-sm-12">
<button type="button" class="btn btn-danger" ng-click="showDeleteModal(id)">Delete</button>
<button type="button" class="btn btn-default" ng-click="gc.save(task)">Save</button>
<button type="button" class="btn btn-default" ng-click="gc.cancel(task)">Cancel</button>
</div>
</div>
<div class="row datacell" ng-class="{'active': model.getTask(id).edit_active}">
<div class="col-sm-1"><p contenteditable="true" ng-model="task.case_name"></p></div>
<div class="col-sm-1"><p contenteditable="true" ng-model="task.title"></p>
....
</div>
</div>
如果该任务的属性edit_active
设置为true
,则ng repeat之后的div用于有条件地显示一组按钮。如果该属性为true,ng-class会向该行添加一个active
的自定义类,如果该行有active
类,我会使用css将其设置为可编辑。
我有一个contenteditable
:的自定义指令
app.directive("contenteditable", function() {
return {
restrict: "A",
require: "ngModel",
link: function(scope, element, attrs, ngModel) {
function read() {
ngModel.$setViewValue(element.html());
}
ngModel.$render = function() {
element.html(ngModel.$viewValue);
};
element.bind("blur keyup change", function() {
scope.$apply(read);
});
function setRowActive(id) {
scope.model.getTask(id).edit_active = true;
}
element.bind("click", function() {
console.log('editing row id ' + scope.id);
scope.$apply(setRowActive(scope.id));
});
}
};
});
这一切都很好,因为它允许用户点击Bootstrap行并编辑值。保存过程非常简单。然而,我正在努力确定如何实现取消流程。如果用户单击了一行并编辑了一个字段。
当我进入gc.cancel()
函数时,模型值已经更新,我所拥有的只是更改后的值。如何恢复原始值?
当您开始编辑时,您可以创建数据的副本,然后在取消时重置所有值吗?
其他答案似乎都没有识别出在自定义指令中,ngModelController
是可用的,它保持了先前的值。因此,只对带下划线前缀的属性进行一次性保存,就可以将初始值保存在对象上。如果取消编辑,则可以检查带前缀的属性。
read()
函数如下所示:
function read() {
// capture old value and save as __property
var property_name = '__' + attrs.ngModel.split('.')[1];
// if no prior property exists, add it
if (!scope.task.hasOwnProperty(property_name)) {
scope.task[property_name] = ngModel.$$lastCommittedViewValue;
}
ngModel.$setViewValue(element.html());
}
因此,如果编辑了task.title
,则会将先前的值保存为task.__title
我认为,解决这种情况的方法是将模型与视图从双向绑定中分离出来,这意味着你应该创建一个服务,向你返回数据模型的副本,你可以在视图中显示和呈现该副本,如果用户单击保存,你会发送服务来更新任务,否则你会要求任务加载旧数据。
为edit
函数和cancel
函数通过id
和task
function gridController (){
// your code here
gc.editing_tasks = {}
gc.edit = function(task, id){
gc.editing_tasks.id = task // so if you are editing multiple task at a time, all of them can save here
// you can use sessionStorage or localStorage instead of saving in an object (I prefer that)
}
gc.cancel = function (id, task){
task = gc.editing_tasks.id
delete gc.editing_tasks.id // no more needed
}
// your code here
}
替代方式
function gridController (){
// your code here
gc.editing_tasks = {}
gc.edit = function(task, id){
gc.editing_tasks.id = task // so if you are editing multiple task at a time, all of them can save here
// you can use sessionStorage or localStorage instead of saving in an object (I prefer that)
}
gc.cancel = function (index){
gc.modelFilter[index] = gc.editing_tasks.id //taking gc.modelFilter as your ng-repeated array
delete gc.editing_tasks.id // no more needed
}
// your code here
}
<button type="button" class="btn btn-default" ng-click="gc.cancel($index)">Cancel</button>
看起来没有"开箱即用";实现编辑取消的方法(近4年后,Angular 9)
您需要在某个地方复制原始状态,并在用户单击"取消"时恢复该状态-正如Jay 所指出的那样
<md-button class="md-raised md-primary md-fab md-mini" ng-click="vm.detail($event, item)">
<md-tooltip>
EDIT
</md-tooltip>
<md-icon>edit</md-icon>
</md-button>
<md-button class="md-raised md-warn" ng-click="vm.cancel()">Cancel</md-button>