Jestem nowy w Angular.js i mam problemy z sortowaniem tablicy i pracą z posortowanymi danymi.
Mam listę z przedmiotami i chcę posortować ją według „Store.storeName”, który do tej pory działa. Ale po posortowaniu danych moja funkcja kasowania już nie działa. Myślę, że to dlatego, że indeks $ jest nieprawidłowy po sortowaniu, a więc złe dane są usuwane.
Jak mogę to rozwiązać? Porządkujesz dane w zakresie, a nie w widoku? Jak to zrobić?
Oto odpowiedni kod:
W widoku:
<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>
A w moim kontrolerze mam tę funkcję usuwania, która powinna usunąć określone dane:
$scope.removeItem = function(index){
$scope.items.splice(index,1);
}
Działa to ładnie przed złożeniem zamówienia w widoku. Jeśli brakuje czegoś ważnego, pozwól mi teraz.
Dzięki!
źródło
Zacząłem uczyć się angulara i stanąłem przed podobnymi problemami i na podstawie odpowiedzi @ pkozlowski-opensource rozwiązałem to po prostu czymś w rodzaju
<a> <img src="img/delete.png" ng-click="removeItem(items.indexOf(item))"> {{items.indexOf(item)}} </a>
źródło
Miałem ten sam problem i inne odpowiedzi w tym temacie nie pasują do mojej sytuacji.
Rozwiązałem swój problem z niestandardowym filtrem:
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; }; });
które można wykorzystać w ten sposób:
<tr ng-repeat="item in items | index | orderBy:'Store.storeName'">
a następnie w HTML możesz użyć
item.index
zamiast$index
.Ta metoda jest odpowiednia dla kolekcji obiektów.
Proszę wziąć pod uwagę, że ten niestandardowy filtr powinien być pierwszym na liście wszystkich zastosowanych filtrów (orderBy itp.) I doda dodatkową właściwość
index
(nazwę można dostosować) do każdego obiektu kolekcji.źródło
$scope.items.splice($scope.items.indexOf(item),1);
będzie również działać zgodnie z oczekiwaniami w przypadku zduplikowanych elementów.(key, item) in items
i to też nie działa. (klucz nie jest zachowany do oryginału)Spróbuj tego:
$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); }
Pełne wyjaśnienie znajdziesz w tym wpisie na moim blogu.
źródło
W przypadku, gdy ktoś potrzebuje użyć
$index
, możesz nadać nazwę posortowanej / przefiltrowanej tablicy:<tr ng-repeat="item in sortedItems = (items | orderBy:'Store.storeName') track by $index">
Zobacz moją odpowiedź tutaj .
źródło
Zostawiłbym tylko komentarz, ale nie mam „reputacji”.
rozwiązanie mile jest dokładnie tym, czego potrzebowałem. Aby odpowiedzieć na pytanie pkozlowski.opensource: jeśli masz zagnieżdżone
ngRepeat
s, listę dynamiczną (np. Tam, gdzie zezwalasz na usuwanie) lub oba (co jest moim przypadkiem), użycie$index
nie działa, ponieważ będzie to zły indeks dla zaplecza dane po sortowaniu i użyciungInit
do buforowania wartości również nie działają, ponieważ nie są ponownie oceniane po zmianie listy.Należy pamiętać, że rozwiązanie mile umożliwia dostosowanie nazwy właściwości dołączonego indeksu przez przekazanie parametru
<tr ng-repeat="item in items | index:'originalPosition' | orderBy:'Store.storeName'">
Moja ulepszona wersja:
.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 ); }); })
źródło