【问题标题】:How can I prevent Angular from re-sorting my list while editing?如何防止 Angular 在编辑时重新排序我的列表?
【发布时间】:2015-07-10 17:11:13
【问题描述】:

我使用 Angular 创建了一个小应用程序来管理 Todolists。每个列表都有许多待办事项。每个 todo 都有属性 name、value1 和 value2。

每个列表都应该由 Angular 自动排序,所以我使用了ng-repeat="todo in selectedList.todos | orderBy: todoOrderFilter"

  <ul class="list-group">
    <li class="list-group-item" ng-repeat="todo in selectedList.todos | orderBy: todoOrderFilter">

      <div>
        <span>{{todo.name}} (Value1: {{todo.value1}}, Value2 {{todo.value2}})</span>
        <button type="button" class="btn btn-warning btn-xs" ng-click="editTodo(todo)"><i class="icon-trash"></i> Edit</button>
        <button type="button" class="btn btn-danger btn-xs floatright" ng-click="deleteTodo(todo)"><i class="icon-trash"></i> Delete</button>
      </div>

    </li>
  </ul>

在我的控制器中,我这样定义了我的订单过滤器:

$scope.todoOrderFilter = function (todo) {
    return todo.value1 * todo.value2;
};

到目前为止,在我尝试使每一行都可编辑之前,它运行良好。为此,我添加了一个额外的 &lt;div&gt; 和输入元素来编辑每个 &lt;li&gt; 中的值,还添加了 ng-hide="todo.editing"ng-show="todo.editing" 以便能够通过简单地设置 todo.editing=truefalse;

完整的 HTML 如下所示:

  <ul class="list-group">
    <li class="list-group-item" ng-repeat="todo in selectedList.todos | orderBy: todoOrderFilter">

      <div ng-hide="todo.editing">
        <span>{{todo.name}} (Value1: {{todo.value1}}, Value2 {{todo.value2}})</span>
        <button type="button" class="btn btn-warning btn-xs" ng-click="editTodo(todo)"><i class="icon-trash"></i> Edit</button>
        <button type="button" class="btn btn-danger btn-xs floatright" ng-click="deleteTodo(todo)"><i class="icon-trash"></i> Delete</button>
      </div>

      <div ng-show="todo.editing">
        <input id="todoname" ng-model="todo.name" ng-enter="updateTodo(todo)" type="text" class="form-control marginBottom" placeholder="Todo speichern" aria-describedby="basic-addon2"></input>
        Value1: <input ng-model="todo.value1" ng-enter="updateTodo(todo)" type="text" class="form-control marginBottom" placeholder="Value1" aria-describedby="basic-addon2"></input>
        Value2: <input ng-model="todo.value2" ng-enter="updateTodo(todo)" type="text" class="form-control marginBottom" placeholder="Value2" aria-describedby="basic-addon2"></input>
        <button type="button" class="btn btn-default" ng-click="updateTodo(todo)">Save</button>
        <button type="button" class="btn btn-danger" ng-click="cancelUpdateTodo(todo)">Cancel</button>
      </div>

    </li>
  </ul>

编辑按钮处理程序:

$scope.editTodo = function(todo) {
    todo.editing = true;
};

这有点工作,但是当我编辑 value1 或 value2 的输入字段时,我的排序功能会自动触发,这会导致 &lt;li&gt; 元素上下跳跃,这真的很糟糕。

所以我基本上想要的是在todo.editing=true 时禁用我的自动排序过滤器。

到目前为止,我在 SO 上发现了这些类似的问题,但它们并没有真正的帮助:


问题:如何防止 Angular 在 todo.editing=true 时使用待办事项列表?

【问题讨论】:

  • 使用您的代码设置一个 plunker。
  • 您可以编辑它的副本并在用户完成编辑时替换原始对象,而不是直接编辑 ng-repeat 中的对象。
  • @rob 是的,这个解决方法成功了,谢谢

标签: javascript html angularjs javascript-databinding


【解决方案1】:

解决方案是编辑对象的副本,而不是直接编辑它。然后,当用户完成编辑时,将原始对象替换为副本。

【讨论】:

    【解决方案2】:

    我坚信使用 Angular 团队已经为我们编写的代码,并以此为基础进行构建。因此,我认为这是装饰内置orderBy 过滤器以接受第四个参数(ignore)的完美场景。

    我自己并没有对此进行过彻底的测试,但它应该可以解决问题;

    app.config(function ($provide) {
      $provide.decorator('orderByFilter', function ($delegate) {
        // Store the last ordered state.
        var previousState;
    
        return function (arr, predicate, reverse, ignore) {
          // If ignore evaluates to a truthy value, return the previous state.
          if (!!ignore) {
            return previousState || arr;
          }
    
          // Apply the regular orderBy filter.
          var order = $delegate.apply(null, arguments);
    
          // Overwrite the previous state with the most recent order state.
          previousState = order;
    
          // Return the latest order state.
          return order;
        }
      });
    });
    

    用法:

    <div ng-repeat="d in data | orderBy:predicate:reverse:ignore">
    
    <!-- in your case -->
    <div ng-repeat="todo in selectedList.todos | orderBy:todoOrderFilter:false:todo.editing>
    

    我希望所有这些都是有意义的(甚至可能只是有效™)。

    【讨论】:

    • 有趣的是,rob 建议在副本上工作做得很好
    猜你喜欢
    • 1970-01-01
    • 2023-03-11
    • 2013-07-08
    • 2018-07-22
    • 2012-06-27
    • 2013-03-21
    • 2010-11-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多