Передача ng-repeat объекта и массива в функцию с помощью _.without

0

Я пытаюсь создать сухие функции для добавления и удаления элементов из массивов. Полезно для редактируемых таблиц. Это влечет за собой передачу объекта и массива функции, использующей lodash _.whithout так что всякий раз, когда строка должна быть удалена из таблицы (или массива в целом), просто передайте объект для удаления и массив, который нужно удалить.

Проблема

Определение массива в функции отлично работает. Объект удаляется, а DOM обновляется. Передача массива в качестве параметра отсутствует. Объект удаляется, но DOM не обновляется.

гипотеза

Угловой - развязывает массив.


Любая идея, как сохранить параметр массива?

Здесь скрипка

Здесь код:

HTML

<table ng-controller="Ctrl">
  <thead>
    <tr>
      <th>
        <input ng-model="newItem" type="number">
      </th>
      <th>
        <button type="button" ng-click="addItemDef(newItem)">Add - Array Defined</button>
      </th>
      <th>
        <button type="button" ng-click="addItemUndef(newItem, items)">Add - Array Undefined</button>
      </th>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="item in items">
      <td>{{item.value}}</td>
      <td>
        <button type="button" ng-click="removeItemDef(item)">Remove - Array Defined</button>
      </td>
      <td>
        <button type="button" ng-click="removeItemUndef(item, items)">Remove - Array Undefined</button>
      </td>
    </tr>
  </tbody>
</table>

Javascript

function Ctrl($scope) {
  $scope.items = [{
    value: 5
  }];

  $scope.addItemDef = function(item) {
    foo = {
        value: item
      }
      //console.log(foo)
    $scope.items.push(foo);
    console.log($scope.items)
  };
  $scope.addItemUndef = function(item, array) {
    thing = {
      value: item
    }
    array.push(thing);
    console.log($scope.items)
  };

  $scope.removeItemDef = function(obj) {
    console.log('Before')
    console.log($scope.items)
      //    var itemWithId = _.find($scope.items, function(item) {
      //      return item.value == obj.value;
      //    });
    $scope.items = _.without($scope.items, obj);
    console.log('After')
    console.log($scope.items)
  };
  //This is the function that does not work
  $scope.removeItemUndef = function(obj, array) {
    console.log('Before')
    console.log(array)
    console.log($scope.items)
      //    var itemWithId = _.find(array, function(item) {
      //      return item.value == obj.value;
      //    });
    array = _.without(array, obj);
    console.log('After')
    console.log(array)
    console.log($scope.items)
  };
};
Теги:
arrays
lodash

1 ответ

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

Это связано с тем, что lodash создает новый массив при вызове _.without.

Затем вы назначаете копию параметру функции, который не влияет на переданный аргумент; вы просто перезаписываете ссылку параметра внутри области функций новой копией с _.without.

// this can't work:
$scope.removeItemUndef = function(obj, array) {
   console.log('Before', array, $scope.items);
   array = _.without(array, obj); // << overwriting reference with no effect
   console.log('After', array, $scope.items);
};

Решение состоит в том, чтобы оставить массив без изменений и изменить внутри этого массива, используя Array.splice.

// this however will work:
$scope.removeItemUndef = function(obj, array) {
   console.log('Before', array, $scope.items);
   var result = _.without(array, obj);
   // remove the current content, and replace with result content:
   Array.prototype.splice.apply(array, [0, array.length].concat(result));
   console.log('After', array, $scope.items);
};

Обновлен jsfiddle

Причина использования Array.prototyp.splice.apply(array,...) а не array.splice(...) заключается в том, что сплайс принимает аргументы распространения вместо массива. Используя трюк .apply, мы можем передать массив.

  • 0
    Так что, если я правильно понимаю, чтобы сохранить привязку, мы объединяем все из связанного массива и заполняем его результатом _.without. Это интересное решение. Я забыл, что Lodash возвращает новый массив.
  • 0
    @ davidcapatch, правильно. Ключ в том, что вам нужно изменить переданный массив (или перезаписать существующий $scope.items с копией, которая уже работала в вашем .removeItemDef ).

Ещё вопросы

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