Cómo filtrar múltiples valores (operación O) en angularJS
Quiero usar filter
angular y quiero filtrar por múltiples valores, si tiene alguno de los valores, entonces debería mostrarse.
Tengo por ejemplo esta estructura:
Un objeto movie
que tiene la propiedad genres
y quiero filtrar por Action
y Comedy
.
Sé que puedo hacerlo filter:({genres: 'Action'} || {genres: 'Comedy'})
, pero qué hacer si quiero filtrarlo dinámicamente. P.ejfilter: variableX
¿Cómo configuro variableX
cuando $scope
tengo una variedad de géneros que tengo que filtrar?
Podría construirlo como una cadena y luego hacer un eval()
pero no quiero usar eval()...
Simplemente crearía un filtro personalizado. No son tan difíciles.
angular.module('myFilters', []).
filter('bygenre', function() {
return function(movies,genres) {
var out = [];
// Filter logic here, adding matches to the out var.
return out;
}
});
plantilla:
<h1>Movies</h1>
<div ng-init="movies = [
{title:'Man on the Moon', genre:'action'},
{title:'Meet the Robinsons', genre:'family'},
{title:'Sphere', genre:'action'}
];" />
<input type="checkbox" ng-model="genrefilters.action" />Action
<br />
<input type="checkbox" ng-model="genrefilters.family" />Family
<br />{{genrefilters.action}}::{{genrefilters.family}}
<ul>
<li ng-repeat="movie in movies | bygenre:genrefilters">{{movie.title}}: {{movie.genre}}</li>
</ul>
Edite aquí está el enlace: Creación de filtros angulares
ACTUALIZACIÓN : Aquí hay un violín que tiene una demostración exacta de mi sugerencia.
Puede utilizar una función de controlador para filtrar.
function MoviesCtrl($scope) {
$scope.movies = [{name:'Shrek', genre:'Comedy'},
{name:'Die Hard', genre:'Action'},
{name:'The Godfather', genre:'Drama'}];
$scope.selectedGenres = ['Action','Drama'];
$scope.filterByGenres = function(movie) {
return ($scope.selectedGenres.indexOf(movie.genre) !== -1);
};
}
HTML:
<div ng-controller="MoviesCtrl">
<ul>
<li ng-repeat="movie in movies | filter:filterByGenres">
{{ movie.name }} {{ movie.genre }}
</li>
</ul>
</div>
Crear un filtro personalizado puede ser excesivo aquí, simplemente puede pasar un comparador personalizado, si tiene valores múltiplos como:
$scope.selectedGenres = "Action, Drama";
$scope.containsComparator = function(expected, actual){
return actual.indexOf(expected) > -1;
};
luego en el filtro:
filter:{name:selectedGenres}:containsComparator
Aquí está la implementación del filtro personalizado, que filtrará los datos utilizando una matriz de valores. Admitirá múltiples objetos clave con una matriz y un valor único de claves. Como se mencionó en el filtro AngularJS API de inangularJS, Doc admite filtros de claves múltiples con un solo valor, pero el filtro personalizado a continuación admitirá la misma característica que angularJS y también admite una matriz de valores y una combinación de matrices y valores únicos de claves. Encuentre el fragmento de código a continuación.
myApp.filter('filterMultiple',['$filter',function ($filter) {
return function (items, keyObj) {
var filterObj = {
data:items,
filteredData:[],
applyFilter : function(obj,key){
var fData = [];
if (this.filteredData.length == 0)
this.filteredData = this.data;
if (obj){
var fObj = {};
if (!angular.isArray(obj)){
fObj[key] = obj;
fData = fData.concat($filter('filter')(this.filteredData,fObj));
} else if (angular.isArray(obj)){
if (obj.length > 0){
for (var i=0;i<obj.length;i++){
if (angular.isDefined(obj[i])){
fObj[key] = obj[i];
fData = fData.concat($filter('filter')(this.filteredData,fObj));
}
}
}
}
if (fData.length > 0){
this.filteredData = fData;
}
}
}
};
if (keyObj){
angular.forEach(keyObj,function(obj,key){
filterObj.applyFilter(obj,key);
});
}
return filterObj.filteredData;
}
}]);
Uso:
arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]}
Aquí hay un ejemplo de violín con la implementación del filtro personalizado "filterMutiple" anterior . :::Ejemplo de violín:::