如何在AngularJS中过滤多个值(进行OR操作)

137
我想使用 Angular 中的 filter 并且想要过滤多个值,如果其中有任意一个则应该显示它。
例如,我有以下结构:
一个对象 movie,它具有属性 genres,我想要过滤 ActionComedy
我知道可以使用 filter:({genres: 'Action'} || {genres: 'Comedy'}),但是如果我想动态过滤呢?例如,filter: variableX
当我需要过滤的类型为数组时,我应该如何在 $scope 中设置 variableX 呢?
我可以将其构造为字符串,然后执行 eval(),但我不想使用 eval()……

17
你确定 filter:({genres: 'Action'} || {genres: 'Comedy'}) 能正常工作吗?在 angular 1.3.16 中它不起作用。 - skilleo
4
1.4.8也一样!它只是不起作用^^ - Alex
20个回答

2

请试试这个

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

2
假设您有两个数组,一个用于电影,另一个用于类型
只需使用过滤器: filter:{genres: genres.type} 这里的"genres"是数组,"type"是类型的值。

1

这是我关于如何创建用于表格的过滤器和指令的例子jsfiddle

该指令接收列表(datas),并创建带有过滤器的表格。

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

如果我能帮到你,我很高兴。


1
我有类似的情况。编写自定义过滤器对我有用。希望这能帮到你! 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>

1

我为字符串和功能编写了这个(我知道这不是问题,但我搜索到这里),也许可以扩展。

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>

1

1

虽然已经有点晚了,但也许这可以帮到某些人:

我们可以分两步来完成,首先按第一个属性进行过滤,然后再按第二个过滤器进行连接:

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

查看具有多属性过滤器的工作示例


0

选项1:使用 Angular 提供的过滤器比较器参数

// declaring a comparator method
$scope.filterBy = function(actual, expected) {
    return _.contains(expected, actual); // uses underscore library contains method
};

var employees = [{name: 'a'}, {name: 'b'}, {name: 'c'}, {name: 'd'}];

// filter employees with name matching with either 'a' or 'c'
var filteredEmployees = $filter('filter')(employees, {name: ['a','c']}, $scope.filterBy);

选项2:使用Angular提供的过滤器否定

var employees = [{name: 'a'}, {name: 'b'}, {name: 'c'}, {name: 'd'}];

// filter employees with name matching with either 'a' or 'c'
var filteredEmployees = $filter('filter')($filter('filter')(employees, {name: '!d'}), {name: '!b'});

-3

我的解决方案

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

在VS 2015上检查过了,它无法识别语法,也无法工作。 - WholeLifeLearner

-14

最佳答案是:

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

5
这是否只是过滤“喜剧”? - user1135469
2
我尝试了这个,它只过滤了“喜剧”,而没有过滤“动作”。 - Ben

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接