AngularJS:同时更新$ scope中的所有对象

时间:2016-09-28 18:03:52

标签: javascript angularjs angularjs-scope

假设我有一个对象存储在$scope中,如此:

$scope.todo = [
  {
    "title" : "Groceries",
    "todoItems" : [
      {
        "title" : "Milk",
        "status" : "Not Done"
      },
      {
        "title" : "Eggs",
        "status" : "Not Done"
      },
      {
        "title" : "Bread",
        "status" : "Done"
      }
    ]
  },
  {
    "title" : "Medical",
    "todoItems" : [
      {
        "title" : "Make eye doctor appointment",
        "status" : "Not Done"
      },
      {
        "title" : "Go to pharmacy",
        "status" : "Not Done"
      },
      {
        "title" : "Take vitamins",
        "status" : "Done"
      }
    ]
  }
];

我正在创建一个允许对每个待办事项进行内联编辑的功能,如下所示:

enter image description here

我通过在名为editMode的待办事项列表项上切换属性来实现此目的。请参阅以下代码块中的第11-14行:

<div ng-app="myApp">
  <div ng-controller="dashBoard">
    <div class="panel panel-default list-[(listID)]" ng-repeat="(listID, todoList) in todo" ng-cloak>
      <div class="panel-heading">[( todoList.title )]</div>
        <ul class="list-group">
          <li ng-repeat="(itemID, todoItem) in todoList.todoItems" data-as-sortable="board.dragControlListeners" data-ng-model="items" class="status-[(todoItem.status)] todo-item todo-item-[(itemID)]" data-as-sortable-item>
            <div class="input-group">
              <span data-as-sortable-item-handle class="input-group-addon">
                <input ng-click="toggleStatus(listID, itemID, todoItem.status)" type="checkbox" ng-checked="todoItem.status == 1">
              </span>
              <span ng-if="!todoItem.editMode" class="todo-item-label-wrapper">
                <div ng-click="toggleEditMode(listID, itemID, 1)" class="todo-item-label">[(todoItem.value)]</div>
              </span>
              <span ng-if="todoItem.editMode" class="todo-input-wrapper">
                <input show-focus="todoItem.editMode" ng-keyup="$event.keyCode == 13 && toggleEditMode(listID, itemID, 0)" type="text" ng-model="todoItem.value" class="form-control">
              </span>
            </div>
          </li>
        </ul>
    </div>
  </div>
</div>

当点击任何给定的待办事项时,它进入编辑模式。 todo项目保持编辑模式,直到用户点击进入。我想让同时在编辑模式下拥有多个待办事项是不可能的。如果你点击todo项目“foo”,然后点击待办事项“bar”,则todo项目“foo”应该切换回只读模式。

我目前通过使用angular.forEach()单独切换每个待办事项来实现此目的,例如:

$scope.toggleEditMode = function(listID, itemID, editMode) {
  $scope.todo[listID].todoItems[itemID].editMode = editMode;

  //Turn off edit mode on every todo item other than the one that was just clicked
  angular.forEach($scope.todo[listID].todoItems, function(todoItem, foreignItemID) {
    if (foreignItemID !== itemID) {
      $scope.todo[listID].todoItems[foreignItemID].editMode = 0;
    }
  });
}

但是我想知道角度是否对我应该使用的这个用例有一些效用。

2 个答案:

答案 0 :(得分:3)

在这种情况下我做的是每个项目都没有editMode属性,而是使用像$scope.currentEditItemId这样的范围变量。然后你做这样的事情:

$scope.toggleEditMode = function (listID, itemID, enableEdit) {
    if (enableEdit === 1) {
        $scope.currentEditItemId = itemId;
        // ... whatever you need to do here
    }
}

HTML看起来像这样:

<span ng-if="itemId != currentEditItemId" class="todo-item-label-wrapper">
    <div ng-click="toggleEditMode(listID, itemID, 1)" class="todo-item-label">[(todoItem.value)]</div>
</span>
<span ng-if="itemId == currentEditItemId" class="todo-input-wrapper">
    <input show-focus="todoItem.id == currentEditItemId" ng-keyup="$event.keyCode == 13 && toggleEditMode(listID, itemID, 0)" type="text" ng-model="todoItem.value" class="form-control">
</span>

答案 1 :(得分:0)

重新审视一下,我意识到可以同时更新范围内的所有内容的一种方法是通过构造函数实例化$scope中的每个项目,然后更新构造函数原型。这并没有真正解决我上面提到的原始用例(可能更好地说明为&#34;更新范围中的所有项目除了一个&#34;)但我认为它仍有一些有用的应用程序。

所以,如果你想要一个项目,当点击它,更新许多其他项目,你可以做这样的事情:

<强> HTML:

  <div ng-app="myApp" ng-controller="toDo">
    <div ng-click="toggleEdit(index)" ng-class="{{item.editable}}"  ng-repeat="(index, item) in items"> {{item.title}} </div>
  </div>

<强> JS:

var app = angular.module('myApp', []);

function newItem(title) {
  this.title = title;
}
newItem.prototype.editable = 'foo';

function toggleAll() {
  newItem.prototype.editable = 'bar';
}

app.controller('toDo', function($scope) {
    $scope.items = []

    for (var i = 0; i <= 10; i++) {
      var item = new newItem("item" + i);
      $scope.items.push(item);
    }

    $scope.toggleEdit = function(index) {
      toggleAll();
    }

});

<强>结果:

在点击任何给定项目时,我们会在所有项目上看到课程foo切换到课程bar

enter image description here