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

IT技术 javascript angularjs angularjs-ng-repeat
2021-01-10 12:13:18

我想使用filterin angular 并希望过滤多个值,如果它具有其中一个值,则应该显示它。

例如,我有这样的结构:

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

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

如何设置variableX$scope,当我有我有过滤器类型的数组?

我可以将它构造为一个字符串,然后执行一个eval()但我不想使用 eval() ...

6个回答

我只想创建一个自定义过滤器。他们没有那么难。

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>

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

更新:这是一个小提琴,其中包含我的建议的确切演示。

要么我有两个值,例如活动和非活动,那么我如何使用此过滤器单独搜索。我们不想制作自定义过滤器。
2021-03-11 12:13:18
那么在输出中我返回我想要显示的电影对象?
2021-03-30 12:13:18
对不起,我花了一段时间才回来。我用一个具体的例子来更新我的答案。
2021-04-07 12:13:18
好的,谢谢,同时我自己弄明白了,但它肯定会在以后帮助某人:)
2021-04-07 12:13:18

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

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>
除了关注点分离之外,是否有任何理由(性能方面)可以避免这种情况?
2021-03-12 12:13:18
javascript 版本,如果其他人正在寻找它: $scope.filteredMovies = $filter('filter')($scope.movies, $scope.filterByGenres);
2021-04-10 12:13:18

在这里创建自定义过滤器可能有点矫枉过正,您可以只传入自定义比较器,如果您有多个值,例如:

$scope.selectedGenres = "Action, Drama"; 

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

然后在过滤器中:

filter:{name:selectedGenres}:containsComparator
帮了我很多。谢谢
2021-03-14 12:13:18
2021-03-15 12:13:18
@chrismarxng-model视图文件中链接到所描述的过滤器的内容是什么?(抱歉,还在学习)——我喜欢你的答案的简单性,并试图让它发挥作用,但不知道如何标记我<input>ng-model. :)
2021-03-19 12:13:18

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

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”自定义过滤器的小提琴示例:::小提琴示例:::

@ZakariaBelghiti 如果您不想返回任何结果,请将代码更改为 if (fData.length > 0){ this.filteredData = fData; }this.filteredData = fData;
2021-03-11 12:13:18
这不适用于带有嵌套对象的 JSON。如果有的话就再理想不过了。它还会length property undefined在控制台中引发错误。
2021-03-20 12:13:18
它对我有用,但如果在列表中找不到搜索的属性,它会返回所有结果,如果列表中不存在该值,我该如何反转此行为并不返回结果?
2021-03-25 12:13:18
@Gerfried 我认为该网站实际上抓取了 Stackoverflow,所以他们窃取了他的答案,而不是相反
2021-03-26 12:13:18
您似乎有正确的意图,但您的示例似乎没有按预期工作。表中的输出似乎相当不一致。
2021-04-06 12:13:18

如果你想过滤对象数组,那么你可以给

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

单个属性将通过为该属性指定的特定过滤器进行过滤。

但是,如果您想按单个属性过滤并全局过滤所有属性,那么您可以执行以下操作。

<tr ng-repeat="supp in $data | filter : filterObject |  filter : search">
其中“filterObject”是用于搜索单个属性的对象,“Search”将在全局范围内搜索每个属性。

~阿图尔

这对我来说效果很好,并且比其他建议将过滤卸载到函数的解决方案更好,因为 AngularJS 在过滤字符串时会进行部分文本匹配。
2021-03-18 12:13:18