如何过滤angularJS中的多个值(OR操作)

我想在角度中使用filter ,并希望过滤多个值,如果它具有任何一个值,那么它应该显示。

我有这样的结构:

一个有属性genres的对象movie ,我想过滤ActionComedy

我知道我可以做filter:({genres: 'Action'} || {genres: 'Comedy'}) ,但如果我想动态地过滤,该怎么办。 例如filter: variableX

如何在$scope设置variableX ,当我有一个流派的数组,我必须过滤?

我可以构造它作为一个字符串,然后做一个eval()但我不想使用eval()…

我只想创建一个自定义过滤器。 他们并不那么辛苦。

 angular.module('myFilters', []). filter('bygenre', function() { return function(movies,genres) { var out = []; // Filter logic here, adding matches to the out var. return out; } }); 

模板:

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

编辑这里是链接: 创建角度过滤器

更新 :这是一个精确的演示我的建议小提琴 。

您可以使用控制器功能进行过滤。

 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> 

创建一个自定义的过滤器可能是过度的,你可以传入一个自定义的比较器,如果你有多个值:

 $scope.selectedGenres = "Action, Drama"; $scope.containsComparator = function(expected, actual){ return actual.indexOf(expected) > -1; }; 

然后在过滤器中:

 filter:{name:selectedGenres}:containsComparator 

这里是自定义过滤器的实现,它将使用数组值来过滤数据。它将支持具有数组和单值键的多个键对象。 正如前面提到的AngularJS API AngularJS过滤器Doc支持多个键值过滤器,但是下面的自定义过滤器将支持与angularJS相同的功能,并且还支持key的数组和值的组合。请查找下面的代码片段,

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

用法:

 arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]} 

这里有一个实现上面的“filterMutiple”自定义过滤器的小例子。 :::小提琴示例:::

如果你想过滤阵列的对象,那么你可以给

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

个人财产将通过为该财产给予特定的过滤器进行过滤。

但是,如果你想要像个人财产过滤和过滤全球所有属性,那么你可以做这样的事情。

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

我花了一些时间,并感谢@chrismarx,我看到了angular的默认filterFilter允许你传递你自己的比较器。 这里是编辑多个值的比较:

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

如果我们想为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); }; }); 

然后我们可以在任何我们想要的地方使用它:

 $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> 

最后,这是一个普朗克 。

注意:预期的数组应该只包含像StringNumber等简单的对象

你可以使用angular.filter的searchField过滤器

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

如果情况允许,你也可以使用ngIf

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

我相信这是你要找的东西:

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

我找到的最快捷的解决方案是使用angular-filter中的filterBy过滤器 ,例如:

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

好处是角度过滤器是一个相当流行的库(在GitHub上约2.6k星),它仍然是积极开发和维护的,因此应该把它作为依赖添加到项目中。

让我们假设你有两个数组,一个用于电影,一个用于流派

只需使用过滤器: filter:{genres: genres.type}

这里的流派是数组和类型,对流派有价值

我写这个字符串和功能(我知道这不是问题,但我搜索它,并在这里),也许它可以扩大。

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

用法:

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

角度或过滤器模块

$filter('orFilter')([{..}, {..} ...], {arg1, arg2, ...}, false)

这里是链接: https : //github.com/webyonet/angular-or-filter

请试试这个

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

我有类似的情况。 编写自定义过滤器为我工作。 希望这可以帮助!

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> 

这里是我的例子如何创建表jsfiddle过滤器和指令

指令获取列表(数据),并创建带有过滤器的表

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

我的荣幸,如果我帮你

加入派对的时间太晚,但可能会帮助某人:

我们可以分两步进行,先按第一个属性过滤,再用第二个过滤器连接:

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

看到多个属性过滤器工作小提琴

我的解决方案

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

最好的答案是:

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