Função de filtro personalizado AngularJS

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)');