Angularjs неправильный $index после orderBy
Я новичок в Angular.js и имею некоторые проблемы, сортируя мой массив и работая над этими отсортированными данными.
У меня есть список с элементами и хочу, чтобы сортировать его по "Store.storeName", который работает до сих пор. Но после сортировки данных моя функция удаления больше не работает. Я думаю, это потому, что после сортировки индекс $неверен, и поэтому неверные данные удаляются.
Как я могу это решить? Заказ данных в области, а не в представлении? Как это сделать?
Вот какой код:
В представлении:
<tr ng-repeat="item in items | orderBy:'Store.storeName'">
<td><input class="toggle" type="checkbox" ng-model="item.Completed"></td>
<td>{{item.Name}}</td>
<td>{{item.Quantity}} Stk.</td>
<td>{{item.Price || 0 | number:2}} €</td>
<td>{{item.Quantity*item.Price|| 0 | number:2}} €</td>
<td>{{item.Store.storeName}}</td>
<td><a><img src="img/delete.png" ng-click="removeItem($index)">{{$index}}</a></td>
</tr>
И в моем контроллере у меня есть эта функция удаления, которая должна удалить определенные данные:
$scope.removeItem = function(index){
$scope.items.splice(index,1);
}
Это хорошо работает перед заказом в представлении.
Если что-то важное отсутствует, позвольте мне сейчас.
Спасибо!
Ответы
Ответ 1
Вместо или ретрансляции на $index
, который, как вы заметили, будет указывать на индекс в отсортированном/отфильтрованном массиве, вы можете передать этот элемент непосредственно своей функции removeItem
:
<a><img src="img/delete.png" ng-click="removeItem(item)">{{$index}}</a>
и измените функцию removeItem
, чтобы найти индекс, используя метод indexOf
массива следующим образом:
$scope.removeItem = function(item){
$scope.items.splice($scope.items.indexOf(item),1);
}
Ответ 2
У меня была та же проблема, и другие ответы в этой теме не подходят для моей ситуации.
Я решил проблему с настраиваемым фильтром:
angular.module('utils', []).filter('index', function () {
return function (array, index) {
if (!index)
index = 'index';
for (var i = 0; i < array.length; ++i) {
array[i][index] = i;
}
return array;
};
});
который можно использовать следующим образом:
<tr ng-repeat="item in items | index | orderBy:'Store.storeName'">
а затем в HTML вы можете использовать item.index
вместо $index
.
Этот метод подходит для коллекций объектов.
Пожалуйста, учтите, что этот настраиваемый фильтр должен быть первым в списке всех примененных фильтров (orderBy и т.д.), и он добавит дополнительное свойство index
(имя настраивается) в каждый объект Коллекция.
Ответ 3
Я начал изучать angular и столкнулся с подобной проблемой, и, основываясь на ответе @pkozlowski-opensource, я решил это просто с чем-то вроде
<a>
<img src="img/delete.png" ng-click="removeItem(items.indexOf(item))">
{{items.indexOf(item)}}
</a>
Ответ 4
Попробуйте следующее:
$scope.remove = function(subtask) {
var idx = $scope.subtasks.indexOf(subtask),
st = $scope.currentTask.subtasks[idx];
// remove from DB
SubTask.remove({'subtaskId': subtask.id});
// remove from local array
$scope.subtasks.splice(idx,1);
}
В моем блоге вы можете найти подробное объяснение в этой записи.
Ответ 5
Я бы просто оставил комментарий, но у меня нет "репутации".
Решение mile - это то, что мне тоже нужно. Чтобы ответить на вопрос pkozlowski.opensource: когда у вас есть либо вложенный ngRepeat
s, динамический список (например, когда вы разрешаете удаление), либо оба (это мой случай), использование $index
не работает, потому что это будет неправильно индекс для исходных данных после сортировки и использования ngInit
для кэширования значения не работает либо потому, что он не переоценивается при изменении списка.
Обратите внимание, что решение "миля" позволяет настраивать имя свойства прикрепленного индекса, передавая параметр <tr ng-repeat="item in items | index:'originalPosition' | orderBy:'Store.storeName'">
Моя измененная версия:
.filter( 'repeatIndex', function repeatIndex()
{
// This filter must be called AFTER 'filter'ing
// and BEFORE 'orderBy' to be useful.
return( function( array, index_name )
{
index_name = index_name || 'index';
array.forEach( function( each, i )
{each[ index_name ] = i;});
return( array );
});
})
Ответ 6
Если кому-то нужно использовать $index
, вы можете указать имя в отсортированном/отфильтрованном массиве:
<tr ng-repeat="item in sortedItems = (items | orderBy:'Store.storeName') track by $index">
Смотрите мой ответ здесь.