Función de filtro personalizado AngularJS

Dentro de mi controlador, me gustaría filtrar una matriz de objetos. Cada uno de estos objetos es un mapa que puede contener cadenas y listas

Intenté usar el formato $filter('filter')(array, function) , pero no sé cómo acceder a los elementos individuales de la matriz dentro de mi función. Aquí hay un fragmento para mostrar lo que quiero.

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

Y luego en el criteriaMatch() , comprobaré si cada una de las propiedades individuales coincide

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

Tengo que hacer todo esto en el controlador y comstackr una lista de listas y configurarlas en el scope. Entonces necesito acceder al $filter('filter') solo de esta manera. Todos los ejemplos que encontré en la red hasta el momento tienen búsquedas de criterios estáticos dentro de la función, no pasan un objeto de criterio y prueban contra cada elemento en la matriz.

Puedes usarlo así: http://plnkr.co/edit/vtNjEgmpItqxX5fdwtPi?p=preview

Como ha encontrado, el filter acepta la función de predicado que acepta elemento por elemento de la matriz. Entonces, solo tiene que crear una función de predicado basada en los criteria dados.

En este ejemplo, criteriaMatch es una función que devuelve una función de predicado que coincide con los criteria dados.

modelo:

 
{{ item }}

scope:

 $scope.criteriaMatch = function( criteria ) { return function( item ) { return item.name === criteria.name; }; }; 

Aquí hay un ejemplo de cómo usaría el filter dentro de su JavaScript AngularJS (en lugar de en un elemento HTML).

En este ejemplo, tenemos una matriz de registros de país, cada uno con un nombre y un código ISO de 3 caracteres.

Queremos escribir una función que busque en esta lista un registro que coincida con un código específico de 3 caracteres.

Así es como lo haríamos sin usar el 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; }; 

Sí, nada de malo en eso.

Pero así es como se vería la misma función, usando 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]; }; 

Mucho más ordenado.

Recuerde que el filter devuelve una matriz como resultado (una lista de registros que coinciden), por lo tanto, en este ejemplo, querremos devolver 1 registro o NULL.

Espero que esto ayude.

Además, si desea utilizar el filtro en su controlador de la misma manera que lo hace aquí:

 
{{ item }}

Podrías hacer algo como:

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