W moim kontrolerze chciałbym przefiltrować tablicę obiektów. Każdy z tych obiektów jest mapą, która może zawierać zarówno ciągi znaków, jak i listy
Próbowałem użyć $filter('filter')(array, function)
formatu, ale nie wiem, jak uzyskać dostęp do poszczególnych elementów tablicy w mojej funkcji. Oto fragment pokazujący, czego chcę.
$filter('filter')(array, function() {
return criteriaMatch(item, criteria);
});
A następnie w sekcji criteriaMatch()
sprawdzę, czy każda z właściwości jest zgodna
var criteriaMatch = function(item, criteria) {
// go thro each individual property in the item and criteria
// and check if they are equal
}
Muszę to wszystko zrobić w kontrolerze i skompilować listę list i ustawić je w zakresie. Muszę więc uzyskać dostęp tylko w $filter('filter')
ten sposób. Wszystkie przykłady, które do tej pory znalazłem w sieci, zawierają statyczne kryteria wyszukiwania wewnątrz funkcji, nie przekazują obiektu kryteriów i nie testują każdego elementu w tablicy.
źródło
Odpowiedzi:
Możesz go używać w ten sposób: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview
Tak jak znalazłeś,
filter
akceptuje funkcję predykatu, która akceptuje element po pozycji z tablicy. Musisz więc po prostu utworzyć funkcję predykatu na podstawie danegocriteria
.W tym przykładzie
criteriaMatch
jest funkcją, która zwraca funkcję predykatu, która pasuje do podanegocriteria
.szablon:
<div ng-repeat="item in items | filter:criteriaMatch(criteria)"> {{ item }} </div>
zakres:
$scope.criteriaMatch = function( criteria ) { return function( item ) { return item.name === criteria.name; }; };
źródło
filter
metody natywnej w obiekcie Array:array.filter(function(item){return item.name === criteria.name;})
Oto przykład, jak należy użyć
filter
w swoim JavaScript AngularJS (zamiast w elemencie HTML).W tym przykładzie mamy tablicę rekordów krajów, z których każdy zawiera nazwę i 3-znakowy kod ISO.
Chcemy napisać funkcję, która przeszuka tę listę w poszukiwaniu rekordu pasującego do określonego 3-znakowego kodu.
Oto, jak byśmy to zrobili bez użycia
filter
:$scope.FindCountryByCode = function (CountryCode) { // Search through an array of Country records for one containing a particular 3-character country-code. // Returns either a record, or NULL, if the country couldn't be found. for (var i = 0; i < $scope.CountryList.length; i++) { if ($scope.CountryList[i].IsoAlpha3 == CountryCode) { return $scope.CountryList[i]; }; }; return null; };
Tak, nic w tym złego.
Ale oto jak wyglądałaby ta sama funkcja, używając
filter
:$scope.FindCountryByCode = function (CountryCode) { // Search through an array of Country records for one containing a particular 3-character country-code. // Returns either a record, or NULL, if the country couldn't be found. var matches = $scope.CountryList.filter(function (el) { return el.IsoAlpha3 == CountryCode; }) // If 'filter' didn't find any matching records, its result will be an array of 0 records. if (matches.length == 0) return null; // Otherwise, it should've found just one matching record return matches[0]; };
Dużo schludniej.
Pamiętaj, że
filter
jako wynik zwraca tablicę (listę pasujących rekordów), więc w tym przykładzie będziemy chcieli zwrócić 1 rekord lub NULL.Mam nadzieję że to pomoże.
źródło
Dodatkowo, jeśli chcesz użyć filtra w swoim kontrolerze w taki sam sposób, jak tutaj:
<div ng-repeat="item in items | filter:criteriaMatch(criteria)"> {{ item }} </div>
Możesz zrobić coś takiego:
var filteredItems = $scope.$eval('items | filter:filter:criteriaMatch(criteria)');
źródło
var filteredItems = $filter('criteriaMatch')(items, criteria);