Редактирование ссылки на переданный аргумент не обновляет модель

0

У меня есть таблица, которая отображает элементы и позволяет встроенное редактирование с возможностью сохранения или отмены изменений.

Каждая строка таблицы содержит столбцы, которые показывают содержимое элемента, когда строка не редактируется, и ввод для редактирования, когда строка находится в режиме редактирования.

Здесь HTML:

<table class="table table-bordered">
  <thead>
    <tr>
      <th>Field A</th>
      <th>Field B</th>
      <th>Field C</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in items">
      <td>
        <span ng-show="editingItem !== item">
          {{item.fieldA}}
        </span>
        <input type="text" ng-model="item.fieldA" class="form-control" ng-show="editingItem === item" />
      </td>
      <td>
        <span ng-show="editingItem !== item">
          {{item.fieldB}}
        </span>
        <input type="text" ng-model="item.fieldB" class="form-control" ng-show="editingItem === item" />
      </td>
      <td>
        <span ng-show="editingItem !== item">
          {{item.fieldC}}
        </span>
        <input type="text" ng-model="item.fieldC" class="form-control" ng-show="editingItem === item" />
      </td>
      <td>
        <i ng-click="startEditItem(item)" ng-show="editingItem !== item" class="fa fa-pencil link text-primary"></i>
        <i ng-click="confirmEditItem(item)" ng-show="editingItem === item" class="fa fa-check link text-success "></i>
        <i ng-click="cancelEditItem(item)" ng-show="editingItem === item" class="fa fa-times link text-danger"></i>
      </td>
    </tr>
  </tbody>
</table>

Код контроллера:

angular.module('myApp', [])
  .controller('myController', function($scope) {
    $scope.items = [{
      id: '1',
      fieldA: 'foo1',
      fieldB: 'bar1',
      fieldC: 'baz1'
    }, {
      id: '2',
      fieldA: 'foo2',
      fieldB: 'bar2',
      fieldC: 'baz2'
    }, {
      id: '3',
      fieldA: 'foo3',
      fieldB: 'bar3',
      fieldC: 'baz3'
    }, ];

    $scope.startEditItem = function(item) {
      //clone, won't point to same reference
      $scope.editingItemCopy = JSON.parse(JSON.stringify(item));
      $scope.editingItem = item;

    }

    $scope.confirmEditItem = function() {
      $scope.editingItem = null;
      // no need to do anything, the model is changed already.
    }

    $scope.cancelEditItem = function(item) {
      $scope.editingItem = null;
      //below line doesn't work
      //item = JSON.parse(JSON.stringify($scope.editingItemCopy));
      for(var i = 0; i < $scope.items.length; i++) {
        if($scope.items[i].id === item.id) {
          $scope.items[i] = JSON.parse(JSON.stringify($scope.editingItemCopy));
        }
      }
    }


  });

Я хочу знать, почему прокомментированная строка в $ scope.cancelEditItem не работает, и мне нужно изменить массив $ scope.items, если переданный аргумент функции должен указывать на один и тот же элемент внутри массива.

Здесь plunkr http://plnkr.co/edit/XF1ytvJ6HYfceaivZhfr?p=preview, не стесняйтесь раскомментировать эту строку и прокомментировать итерацию массива, чтобы увидеть, о чем я говорю.

Теги:
arrays

1 ответ

1
Лучший ответ

Когда вы назначаете объект этому элементу, он не совпадает с $scope.items[0] = и вы теряете ссылку на объект в $ scope.items, что вы можете сделать, это манипулировать объектом item то есть следующий код будет работать как объект не уничтожается или не перезаписывается другим объектом, но атрибуты значения изменяются

$scope.cancelEditItem = function (item) {
    $scope.editingItem = null;
    item = angular.extend(item, $scope.editingItemCopy);
}

Примечание: вместо JSON.parse(JSON.stringify(xxx)) вы можете делать angular.copy(xxx)

  • 0
    Ааа, понятно, спасибо за совет по angular.copy, не знал об этом. Ваш код работал, и после дальнейшего изучения я нашел это превосходное объяснение передачи по значению JavaScript или передачи по ссылке, которое помогло прояснить эту проблему: stackoverflow.com/questions/518000/…
  • 1
    Рад помочь, сохраните эту информацию в безопасности на случай, если вы начнете использовать двустороннюю привязку данных через сервис, где вы будете использовать эти принципы. ура

Ещё вопросы

Сообщество Overcoder
Наверх
Меню