【问题标题】:Implementing a cancel edit in Angular在 Angular 中实现取消编辑
【发布时间】:2020-06-29 03:49:21
【问题描述】:

我在 gridController as gc 中有一个 ng-repeat,用于填充 Bootstrap 表:

<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 用于有条件地显示一组按钮。如果该属性为真,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));
    });
  }
};

});

这一切都很好,因为它允许用户单击引导行并编辑值。保存过程很简单。但是我正在尝试确定如何实施取消过程。如果用户点击了一行并编辑了一个字段。

当我到达gc.cancel() 函数时,模型值已经更新,我所拥有的只是更改后的值。如何恢复原值?

【问题讨论】:

  • 在指令中,您只能复制模型并在取消时恢复。如果您可以考虑将指令移动到组件(您应该这样做),您可以使用 $onChanges 挂钩的单向数据绑定

标签: javascript css angularjs


【解决方案1】:

当你开始编辑时,你可以创建一个数据的副本,然后你可以在它们取消时重置所有值吗?

【讨论】:

    【解决方案2】:

    其他答案似乎都没有认识到在自定义指令中,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

    【讨论】:

      【解决方案3】:

      我认为您的情况的答案是将模型从视图中分离出来,形成 2-way-bindings,这意味着您应该创建一个服务来返回您显示和渲染的数据模型的副本在视图中,如果用户点击保存则发送服务更新任务,否则重新请求任务加载旧数据。

      【讨论】:

      • 这将是功能性的,但它意味着复制整个模型。列数比我的代码中描述的多得多,行数也很多。
      • 你应该实现分页,并且一次复制 X 行
      【解决方案4】:

      idtask 传递给edit 函数和cancel 函数

      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
      }
      &lt;button type="button" class="btn btn-default" ng-click="gc.cancel($index)"&gt;Cancel&lt;/button&gt;

      【讨论】:

        【解决方案5】:

        似乎没有“开箱即用”的方式来实现取消编辑(近 4 年过去了,Angular 9)

        您需要在某处获取原始状态的副本并在用户单击取消时恢复该状态 - 正如 Jay 所指出的那样

        【讨论】:

          【解决方案6】:

          <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>

          【讨论】:

          • 编辑edit取消
          猜你喜欢
          • 2022-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-09-14
          • 1970-01-01
          • 2012-12-21
          • 2018-10-15
          • 1970-01-01
          相关资源
          最近更新 更多