2013-05-10 15 views
76

Wewnątrz kontrolera chciałbym filtrować tablicę obiektów. Każdy z tych obiektów to mapa, która może zawierać ciągi znaków oraz listy. Próbowałem używać formatu $filter('filter')(array, function), ale nie wiem, jak uzyskać dostęp do poszczególnych elementów tablicy wewnątrz mojej funkcji. Oto fragment, który pokazuje, czego chcę.Funkcja filtra niestandardowego AngularJS

$filter('filter')(array, function() { 
    return criteriaMatch(item, criteria); 
}); 

A potem w criteriaMatch() będę sprawdzić, czy każdy z poszczególnych nieruchomości mecze

var criteriaMatch = function(item, criteria) { 
    // go thro each individual property in the item and criteria 
    // and check if they are equal 
} 

muszę zrobić wszystko to w kontrolerze i sporządzić listę list i ustawić je w zakres. Muszę więc uzyskać dostęp do $filter('filter') tylko w ten sposób. Wszystkie przykłady znalezione w sieci do tej pory mają wyszukiwane kryteria statyczne wewnątrz funkcji, nie przekazują obiektu kryteriów i nie testują każdego elementu w tablicy.

+3

Dlaczego potrzebujesz filtra? Zwykle filtry są używane z szablonów. Czy możesz nie tylko mieć zwykłą funkcję w swoim kontrolerze, jeśli używasz jej tylko tam? – Ketan

+0

zamiast ręcznie przechodzić przez każdy element tablicy, myślałem, że możemy użyć funkcji filtru ("filter") kątowej (która zajmie się iterowaniem thro każdego elementu, jeśli tylko określimy funkcję predykatu) – user2368436

Odpowiedz

154

Można go używać tak: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview

Jakbyś znaleziono filter akceptuje źródłowe funkcję, która przyjmuje pozycję przez element z tablicy. Po prostu musisz utworzyć funkcję predykatu na podstawie podanej criteria.

W tym przykładzie criteriaMatch jest funkcją, która zwraca predykatową funkcję , która pasuje do podanej criteria.

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; 
    }; 
}; 
+0

Nie będę być przy użyciu tego kryterium funkcja Match z html .. w jaki sposób można go wywołać z wewnątrz kontrolera jest to prawidłowe? $ filter ('filter') (array, function() {return criteriaMatch (item, criteria);}); – user2368436

+5

Jeśli nie używasz go w szablonie, zdefiniowanie filtru nie daje żadnych korzyści. Możesz po prostu zdefiniować prostą funkcję javascript, ponieważ jest jeszcze krótsza. Możesz użyć natywnej metody 'filter' w obiekcie Array:' array.filter (function (item) {return item.name === criteria.name;}) ' – Tosh

+0

Mam funkcję javascript. chciałem tylko upewnić się, że kątowe nie ma prostszego sposobu robienia tego .. przyjmuję twoją odpowiedź. dzięki. – user2368436

0

Dodatkowo, jeśli chcesz użyć filtra w kontrolerze w ten sam sposób to zrobić tutaj:

<div ng-repeat="item in items | filter:criteriaMatch(criteria)"> 
    {{ item }} 
</div> 

Ty może zrobić coś takiego:

var filteredItems = $scope.$eval('items | filter:filter:criteriaMatch(criteria)'); 
+4

Alternatywnie, 'var filtersItems = $ filter ('criteriaMatch') (elementy, kryteria);' – 321zeno

2

Oto przykład, w jaki sposób używałbyś filter w twoim AngularJS JavaScript (zamiast w elemencie HTML).

W tym przykładzie mamy tablicę rekordów krajowych, z których każdy zawiera nazwę i 3-znakowy kod ISO.

Chcemy napisać funkcję, która przeszuka tę listę dla rekordu, który pasuje do określonego 3-znakowego kodu.

Oto jak chcielibyśmy zrobić to bez użyciu 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 złego.

Ale oto jak ta sama funkcja będzie wyglądać, wykorzystują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]; 
}; 

Znacznie neater.

Pamiętaj, że filter zwraca tablicę jako wynik (listę pasujących rekordów), więc w tym przykładzie będziemy albo chcieli zwrócić 1 rekord, albo NULL.

Mam nadzieję, że to pomoże.

Powiązane problemy