Я пытаюсь создать сухие функции для добавления и удаления элементов из массивов. Полезно для редактируемых таблиц. Это влечет за собой передачу объекта и массива функции, использующей 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)
};
};
Это связано с тем, что 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);
};
Причина использования Array.prototyp.splice.apply(array,...)
а не array.splice(...)
заключается в том, что сплайс принимает аргументы распространения вместо массива. Используя трюк .apply
, мы можем передать массив.
$scope.items
с копией, которая уже работала в вашем.removeItemDef
).