在Angular中实现取消编辑



我在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函数通过idtask

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>

最新更新