Dentro do meu controlador, gostaria de filtrar uma matriz de objects. Cada um desses objects é um mapa que pode conter cadeias de caracteres, bem como listas
Eu tentei usar o formato $filter('filter')(array, function)
, mas eu não sei como acessar os elementos individuais da matriz dentro da minha function. Aqui está um trecho para mostrar o que eu quero.
$filter('filter')(array, function() { return criteriaMatch(item, criteria); });
E, em seguida, no criteriaMatch()
, vou verificar se cada uma das propriedades individuais corresponde
var criteriaMatch = function(item, criteria) { // go thro each individual property in the item and criteria // and check if they are equal }
Eu tenho que fazer tudo isso no controlador e compilar uma lista de listas e defini-las no escopo. Então eu preciso acessar o $filter('filter')
apenas desta maneira. Todos os exemplos que encontrei na rede até agora possuem pesquisas de critérios estáticos dentro da function, eles não passam um object de critério e testam cada item na matriz.
Você pode usá-lo assim: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview
Como você descobriu, o filter
aceita a function de predicado que aceita item por item da matriz. Então, você só precisa criar uma function de predicado com base nos criteria
fornecidos.
Neste exemplo, criteriaMatch
é uma function que retorna uma function de predicado que corresponde aos criteria
fornecidos.
modelo:
{{ item }}
escopo:
$scope.criteriaMatch = function( criteria ) { return function( item ) { return item.name === criteria.name; }; };
Veja um exemplo de como você usaria o filter
em seu JavaScript do AngularJS (em vez de em um elemento HTML).
Neste exemplo, temos uma matriz de registros de países, cada um contendo um nome e um código ISO de três caracteres.
Queremos escrever uma function que pesquisará através desta lista por um registro que corresponda a um código específico de 3 caracteres.
Veja como faríamos sem usar o 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; };
Sim, nada de errado com isso.
Mas aqui está como a mesma function ficaria, usando o 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]; };
Muito mais puro.
Lembre-se que o filter
retorna uma matriz como resultado (uma lista de registros correspondentes), portanto, neste exemplo, queremos retornar 1 registro ou NULL.
Espero que isto ajude.
Além disso, se você quiser usar o filtro no seu controlador da mesma maneira que você faz aqui:
{{ item }}
Você poderia fazer algo como:
var filteredItems = $scope.$eval('items | filter:filter:criteriaMatch(criteria)');