108

看看这里的例子: http ://docs.angularjs.org/api/ng.filter:filter

您可以使用任何电话属性进行<input ng-model="search">搜索,也可以使用 仅通过姓名进行搜索,<input ng-model="search.name">结果将按姓名适当过滤(如预期的那样,键入电话号码不会返回任何结果)。

假设我有一个具有“name”属性、“phone”属性和“secret”属性的模型,我将如何通过“name”和“phone”属性而不是“secret”属性进行过滤? 因此,从本质上讲,用户可以输入姓名或电话号码,并且会正确过滤,但即使用户输入的值等于“秘密”值的一部分,它也不会返回任何内容。ng-repeat

谢谢。

4

13 回答 13

172

这是plunker

具有更简洁代码的新 plunker,其中查询和搜索列表项均不区分大小写

主要思想是创建一个过滤函数来实现这个目的。

来自官方文档

函数:谓词函数可用于编写任意过滤器。为数组的每个元素调用该函数。最终结果是谓词返回 true 的那些元素的数组。

<input ng-model="query">

<tr ng-repeat="smartphone in smartphones | filter: search "> 

$scope.search = function(item) {
    if (!$scope.query || (item.brand.toLowerCase().indexOf($scope.query) != -1) || (item.model.toLowerCase().indexOf($scope.query.toLowerCase()) != -1) ){
        return true;
    }
    return false;
};

更新

有些人可能会担心现实世界中的表现,这是正确的。

在现实世界中,我们可能会从控制器中进行这种过滤。

这是详细的帖子,展示了如何做到这一点。

简而言之,我们添加ng-change输入以监控新的搜索变化

然后触发过滤功能。

于 2012-11-04T05:20:36.770 回答
80

您可以将 Object 作为参数传递给过滤器表达式,如API 参考中所述。该对象可以选择性地应用您感兴趣的属性,如下所示:

<input ng-model="search.name">
<input ng-model="search.phone">
<input ng-model="search.secret">
<tr ng-repeat="user in users | filter:{name: search.name, phone: search.phone}">

这是一个Plunker

注意...这个例子在 AngularJS 1.1.5 中效果很好,但在 1.0.7 中并不总是那么好。在此示例中,1.0.7 将初始化所有过滤掉的内容,然后在您开始使用输入时工作。它的行为就像输入中包含不匹配的值,即使它们开始为空白。如果您想继续使用稳定版本,请继续尝试针对您的情况进行此操作,但在某些情况下可能需要使用 @maxisam 的解决方案,直到 1.2.0 发布。

于 2013-06-19T14:07:33.303 回答
5

我从@maxisam 的回答中启发了自己,并创建了自己的排序功能,尽管我会分享它(因为我很无聊)。

情况 我想通过一系列汽车进行过滤。要过滤的选定属性是名称、年份、价格和公里。房产价格和公里数是数字(因此使用.toString)。我还想控制大写字母(因此.toLowerCase)。此外,我希望能够将过滤器查询拆分为不同的单词(例如,给定过滤器 2006 Acura,它会找到与年份匹配的 2006 和带有名称的 Acura)。

我传递给过滤器的函数

        var attrs = [car.name.toLowerCase(), car.year, car.price.toString(), car.km.toString()],
            filters = $scope.tableOpts.filter.toLowerCase().split(' '),
            isStringInArray = function (string, array){
                for (var j=0;j<array.length;j++){
                    if (array[j].indexOf(string)!==-1){return true;}
                }
                return false;
            };

        for (var i=0;i<filters.length;i++){
            if (!isStringInArray(filters[i], attrs)){return false;}
        }
        return true;
    };
于 2013-11-28T18:25:29.710 回答
5

如果您愿意使用第三方库,那么带有一系列过滤器的“Angular Filters”可能会很有用:

https://github.com/a8m/angular-filter#filterby

collection | filterBy: [prop, nested.prop, etc..]: search
于 2015-08-24T00:07:57.943 回答
3

希望这个答案会有所帮助,多值过滤器

这个小提琴中的工作示例

arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]}
于 2014-01-16T18:33:06.340 回答
2

这里有很多很好的解决方案,但我建议走另一条路。如果搜索是最重要的事情并且视图上根本没有使用“秘密”属性;我的方法是使用具有所有优点的内置角度过滤器,并将模型简单地映射到新的对象数组。

问题示例:

$scope.people = members.map(function(member) { 
                              return { 
                                name: member.name, 
                                phone: member.phone
                              }});

现在,在 html 中只需使用常规过滤器来搜索这两个属性。

<div ng-repeat="member in people | filter: searchString">
于 2016-02-20T12:05:50.817 回答
2

在angularJs中使用filterBy非常简单的方法

对于工作 plnkr,请点击此链接

http://plnkr.co/edit/US6xE4h0gD5CEYV0aMDf?p=preview

这专门使用单个属性来搜索多个列但不是全部。

<!DOCTYPE html>
<html ng-app="myApp">

  <head>
    <script data-require="angular.js@1.4.1" data-semver="1.4.1" src="https://code.angularjs.org/1.4.1/angular.js"></script>
    <script data-require="angular-filter@0.5.2" data-semver="0.5.2" src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.2/angular-filter.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="myCtrl as vm">
  <input type="text" placeholder="enter your search text" ng-model="vm.searchText" />
   <table>
     <tr ng-repeat="row in vm.tableData | filterBy: ['col1','col2']: vm.searchText">
       <td>{{row.col1}}</td>
       <td>{{row.col2}}</td>
       <td>{{row.col3}}</td>
     </tr>
   </table>
   <p>This will show filter from <b>two columns</b> only(col1 and col2) . Not from all. Whatever columns you add into filter array they
   will be searched. all columns will be used by default if you use <b>filter: vm.searchText</b></p>
  </body>
</html>

控制器

// Code goes here
(function(){

  var myApp = angular.module('myApp',['angular.filter']);

  myApp.controller('myCtrl', function($scope){
    var vm= this;
    vm.x = 20;

    vm.tableData = [
      {
        col1: 'Ashok',
        col2: 'Tewatia',
        col3: '12'
      },{
        col1: 'Babita',
        col2: 'Malik',
        col3: '34'
      },{
        col1: 'Dinesh',
        col2: 'Tewatia',
        col3: '56'
      },{
        col1: 'Sabita',
        col2: 'Malik',
        col3: '78'
      }
      ];
  })

})();
于 2017-05-03T07:13:00.117 回答
2

我简单地解决了这个问题:

<div ng-repeat="Object in List | filter: (FilterObj.FilterProperty1 ? {'ObjectProperty1': FilterObj.FilterProperty1} : '') | filter:(FilterObj.FilterProperty2 ? {'ObjectProperty2': FilterObj.FilterProperty2} : '')">
于 2019-06-28T13:17:55.613 回答
1

http://plnkr.co/edit/A2IG03FLYnEYMpZ5RxEm?p=preview

这是一个区分大小写的搜索,它还将您的搜索分成要在每个模型中搜索的单词。只有当它找到一个空格时,它才会尝试将查询拆分为一个数组,然后搜索每个单词。

如果每个单词至少在其中一个模型中,则返回 true。

$scope.songSearch = function (row) {
    var query = angular.lowercase($scope.query);
    if (query.indexOf(" ") > 0) {
        query_array = query.split(" ");
        search_result = false;
        for (x in query_array) {
            query = query_array[x];
            if (angular.lowercase(row.model1).indexOf(query || '') !== -1 || angular.lowercase(row.model2).indexOf(query || '') !== -1 || angular.lowercase(row.model3).indexOf(query || '') !== -1){
                search_result = true;
            } else {
                search_result = false;
                break;
            }
        }
        return search_result;
    } else {
        return (angular.lowercase(row.model1).indexOf(query || '') !== -1 || angular.lowercase(row.model2).indexOf(query || '') !== -1 || angular.lowercase(row.model3).indexOf(query || '') !== -1);
    }
};
于 2015-08-17T08:43:27.550 回答
1

过滤器可以是带有字段的 JavaScript 对象,您可以将表达式设置为:

ng-repeat= 'item in list | filter :{property:value}'
于 2016-07-14T06:14:21.963 回答
0

我喜欢尽可能保持简单。我需要按国际分组,过滤所有列,显示每个组的计数并在不存在项目时隐藏组。

另外,我不想仅仅为这样简单的事情添加自定义过滤器。

        <tbody>
            <tr ng-show="fusa.length > 0"><td colspan="8"><h3>USA ({{fusa.length}})</h3></td></tr>
            <tr ng-repeat="t in fusa = (usa = (vm.assignmentLookups | filter: {isInternational: false}) | filter: vm.searchResultText)">
                <td>{{$index + 1}}</td>
                <td ng-bind-html="vm.highlight(t.title, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.genericName, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.mechanismsOfAction, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.diseaseStateIndication, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.assignedTo, vm.searchResultText)"></td>
                <td ng-bind-html="t.lastPublished | date:'medium'"></td>
            </tr>
        </tbody>
        <tbody>
            <tr ng-show="fint.length > 0"><td colspan="8"><h3>International ({{fint.length}})</h3></td></tr>
            <tr ng-repeat="t in fint = (int = (vm.assignmentLookups | filter: {isInternational: true}) | filter: vm.searchResultText)">
                <td>{{$index + 1}}</td>
                <td ng-bind-html="vm.highlight(t.title, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.genericName, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.mechanismsOfAction, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.diseaseStateIndication, vm.searchResultText)"></td>
                <td ng-bind-html="vm.highlight(t.assignedTo, vm.searchResultText)"></td>
                <td ng-bind-html="t.lastPublished | date:'medium'"></td>
            </tr>
        </tbody>
于 2015-08-10T19:54:36.253 回答
0

我可能会很晚,但这就是我最终要做的。我做了一个非常通用的过滤器。

angular.module('app.filters').filter('fieldFilter', function() {
        return function(input, clause, fields) {
            var out = [];
            if (clause && clause.query && clause.query.length > 0) {
                clause.query = String(clause.query).toLowerCase();
                angular.forEach(input, function(cp) {
                    for (var i = 0; i < fields.length; i++) {
                        var haystack = String(cp[fields[i]]).toLowerCase();
                        if (haystack.indexOf(clause.query) > -1) {
                            out.push(cp);
                            break;
                        }
                    }
                })
            } else {
                angular.forEach(input, function(cp) {
                    out.push(cp);
                })
            }
            return out;
        }

    })

然后像这样使用它

<tr ng-repeat-start="dvs in devices |  fieldFilter:search:['name','device_id']"></tr>

你的搜索框就像

<input ng-model="search.query" class="form-control material-text-input" type="text">

其中 name 和 device_id 是 dvs 中的属性

于 2018-05-16T10:18:41.017 回答
-1

对于那些想要快速过滤对象的人来说,这是一个简单的解决方案:

<select>
  <option ng-repeat="card in deck.Cards | filter: {Type: 'Face'}">{{card.Name}}</option>
</select>

数组过滤器可让您模仿您尝试过滤的对象。在上述情况下,以下类可以正常工作:

var card = function(name, type) {
  var _name = name;
  var _type = type;

  return {
    Name: _name,
    Type: _type
  };
};

甲板可能看起来像:

var deck = function() {
  var _cards = [new card('Jack', 'Face'),
                new card('7', 'Numeral')];

  return {
    Cards: _cards
  };
};

如果要过滤对象的多个属性,只需用逗号分隔字段名称:

<select>
  <option ng-repeat="card in deck.Cards | filter: {Type: 'Face', Name: 'Jack'}">{{card.Name}}</option>
</select>

编辑:这是一个工作 plnkr,它提供了单个和多个属性过滤器的示例:

http://embed.plnkr.co/i0wCx6l1WPYljk57SXzV/

于 2014-11-25T22:01:00.000 回答