values property multiple make array javascript angularjs angularjs-ng-repeat

javascript - property - make filter angularjs



Cómo filtrar valores múltiples(operación OR) en angularJS (19)

Aquí está la implementación del filtro personalizado, que filtrará los datos utilizando un conjunto de valores. Admitirá múltiples objetos clave con una matriz y un valor único de claves. Como se menciona enangularJS API AngularJS, el filtro Doc admite múltiples filtros de clave con un solo valor, pero debajo del filtro personalizado admitirá la misma función que angularJS y también admite una matriz de valores y una combinación de matriz y valor único 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. ::: Fiddle Example :::

Quiero usar el filter en angular y quiero filtrar por valores múltiples; si tiene uno de los valores, entonces debería mostrarse.

Tengo por ejemplo esta estructura:

Una movie objeto que tiene los genres la propiedad y quiero filtrar para Action and Comedy .

Sé que puedo filter:({genres: ''Action''} || {genres: ''Comedy''}) , pero qué hacer si quiero filtrarlo dinámicamente. Ej filter: variableX

¿Cómo configuro la variableX en $scope , cuando tengo una matriz de géneros que debo filtrar?

Podría construirlo como una cadena y luego hacer un eval() pero no quiero usar eval () ...


Aquí está mi ejemplo de cómo crear filtro y directiva para la tabla jsfiddle

directiva obtener lista (datos) y crear tabla con filtros

<div ng-app="autoDrops" ng-controller="HomeController"> <div class="row"> <div class="col-md-12"> <h1>{{title}}</h1> <ng-Multiselect array-List="datas"></ng-Multiselect> </div> </div> </div>

es un placer si te ayudo


Crear un filtro personalizado puede ser exagerado aquí, simplemente puede pasar un comparador personalizado, si tiene los 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


Creo que esto es lo que estás buscando:

<div>{{ (collection | fitler1:args) + (collection | filter2:args) }}</div>


Demasiado tarde para unirse a la fiesta, pero puede ser que pueda ayudar a alguien:

Podemos hacerlo en dos pasos, primero filtrar por la primera propiedad y luego concatenar por segundo filtro:

$scope.filterd = $filter(''filter'')($scope.empList, { dept: "account" }); $scope.filterd = $scope.filterd.concat($filter(''filter'')($scope.empList, { dept: "sales" }));

Ver el violín de trabajo con filtro de propiedad múltiple


Escribí esto para la funcionalidad de cadenas Y (sé que no es la pregunta, pero la busqué y obtuve aquí), tal vez se puede ampliar.

String.prototype.contains = function(str) { return this.indexOf(str) != -1; }; String.prototype.containsAll = function(strArray) { for (var i = 0; i < strArray.length; i++) { if (!this.contains(strArray[i])) { return false; } } return true; } app.filter(''filterMultiple'', function() { return function(items, filterDict) { return items.filter(function(item) { for (filterKey in filterDict) { if (filterDict[filterKey] instanceof Array) { if (!item[filterKey].containsAll(filterDict[filterKey])) { return false; } } else { if (!item[filterKey].contains(filterDict[filterKey])) { return false; } } } return true; }); }; });

Uso:

<li ng-repeat="x in array | filterMultiple:{key1: value1, key2:[value21, value22]}">{{x.name}}</li>


He pasado un tiempo y gracias a @chrismarx, vi que filterFilter predeterminado de filterFilter permite pasar su propio comparador. Aquí está el comparador editado para múltiples valores:

function hasCustomToString(obj) { return angular.isFunction(obj.toString) && obj.toString !== Object.prototype.toString; } var comparator = function (actual, expected) { if (angular.isUndefined(actual)) { // No substring matching against `undefined` return false; } if ((actual === null) || (expected === null)) { // No substring matching against `null`; only match against `null` return actual === expected; } // I edited this to check if not array if ((angular.isObject(expected) && !angular.isArray(expected)) || (angular.isObject(actual) && !hasCustomToString(actual))) { // Should not compare primitives against objects, unless they have custom `toString` method return false; } // This is where magic happens actual = angular.lowercase('''' + actual); if (angular.isArray(expected)) { var match = false; expected.forEach(function (e) { e = angular.lowercase('''' + e); if (actual.indexOf(e) !== -1) { match = true; } }); return match; } else { expected = angular.lowercase('''' + expected); return actual.indexOf(expected) !== -1; } };

Y si queremos hacer un filtro personalizado para DRY:

angular.module(''myApp'') .filter(''filterWithOr'', function ($filter) { var comparator = function (actual, expected) { if (angular.isUndefined(actual)) { // No substring matching against `undefined` return false; } if ((actual === null) || (expected === null)) { // No substring matching against `null`; only match against `null` return actual === expected; } if ((angular.isObject(expected) && !angular.isArray(expected)) || (angular.isObject(actual) && !hasCustomToString(actual))) { // Should not compare primitives against objects, unless they have custom `toString` method return false; } console.log(''ACTUAL EXPECTED'') console.log(actual) console.log(expected) actual = angular.lowercase('''' + actual); if (angular.isArray(expected)) { var match = false; expected.forEach(function (e) { console.log(''forEach'') console.log(e) e = angular.lowercase('''' + e); if (actual.indexOf(e) !== -1) { match = true; } }); return match; } else { expected = angular.lowercase('''' + expected); return actual.indexOf(expected) !== -1; } }; return function (array, expression) { return $filter(''filter'')(array, expression, comparator); }; });

Y luego podemos usarlo en cualquier lugar que deseemos:

$scope.list=[ {name:''Jack Bauer''}, {name:''Chuck Norris''}, {name:''Superman''}, {name:''Batman''}, {name:''Spiderman''}, {name:''Hulk''} ]; <ul> <li ng-repeat="item in list | filterWithOr:{name:[''Jack'',''Chuck'']}"> {{item.name}} </li> </ul>

Finalmente aquí hay un plunkr .

Nota: la matriz esperada solo debe contener objetos simples como cadena , número , etc.


La solución más rápida que he encontrado es usar el filtro filterBy filtro angular-filter , por ejemplo:

<input type="text" placeholder="Search by name or genre" ng-model="ctrl.search"/> <ul> <li ng-repeat="movie in ctrl.movies | filterBy: [''name'', ''genre'']: ctrl.search"> {{movie.name}} ({{movie.genre}}) - {{movie.rating}} </li> </ul>

Lo bueno es que angular.filter es una biblioteca bastante popular (~ 2.6k estrellas en GitHub) que todavía se desarrolla y mantiene activamente, por lo que debería estar bien agregarlo a su proyecto como una dependencia.


Mi solución

ng-repeat="movie in movies | filter: {''Action''} + filter: {''Comedy}"


Por favor, intente esto

var m = angular.module(''yourModuleName''); m.filter(''advancefilter'', [''$filter'', function($filter){ return function(data, text){ var textArr = text.split('' ''); angular.forEach(textArr, function(test){ if(test){ data = $filter(''filter'')(data, test); } }); return data; } }]);


Puede usar 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>


Si desea filtrar en Matriz de objetos, puede dar

filter:({genres: ''Action'', key :value }.

La propiedad individual será filtrada por un filtro particular dado para esa propiedad.

Pero si desea algo como filtrar por propiedad individual y filtrar globalmente para todas las propiedades, entonces puede hacer algo como esto.

<tr ng-repeat="supp in $data | filter : filterObject | filter : search">

Donde "filterObject" es un objeto para buscar una propiedad individual y "Search" buscará en cada propiedad globalmente.

~ Atul


Solo 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; } });

modelo:

<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í el enlace: Crear filtros angulares

ACTUALIZACIÓN : Aquí hay un fiddle que tiene una demostración exacta de mi sugerencia.


Supongamos que tiene dos matrices, una para películas y otra para género

Simplemente use el filtro como: filter:{genres: genres.type}

Aquí los géneros son la matriz y el tipo tiene valor para el género


También puede usar ngIf si la situación lo permite:

<div ng-repeat="p in [ { name: ''Justin'' }, { name: ''Jimi'' }, { name: ''Bob'' } ]" ng-if="[''Jimi'', ''Bob''].indexOf(e.name) > -1"> {{ p.name }} is cool </div>


Tuve una situación similar. Escribir un filtro personalizado funcionó para mí. ¡Espero que esto ayude!

JS:

App.filter(''searchMovies'', function() { return function (items, letter) { var resulsts = []; var itemMatch = new RegExp(letter, ''i''); for (var i = 0; i < items.length; i++) { var item = items[i]; if ( itemMatch.test(item.name) || itemMatch.test(item.genre)) { results.push(item); } } return results; }; });

HTML:

<div ng-controller="MoviesCtrl"> <ul> <li ng-repeat="movie in movies | searchMovies:filterByGenres"> {{ movie.name }} {{ movie.genre }} </li> </ul> </div>


la mejor respuesta es:

filter:({genres: ''Action'', genres: ''Comedy''}


puede usar searchField filter of angular.filter

JS:

$scope.users = [ { first_name: ''Sharon'', last_name: ''Melendez'' }, { first_name: ''Edmundo'', last_name: ''Hepler'' }, { first_name: ''Marsha'', last_name: ''Letourneau'' } ];

HTML:

<input ng-model="search" placeholder="search by full name"/> <th ng-repeat="user in users | searchField: ''first_name'': ''last_name'' | filter: search"> {{ user.first_name }} {{ user.last_name }} </th> <!-- so now you can search by full name -->