使用ng-repeat按多列过滤

时间:2013-12-31 00:21:54

标签: angularjs

我想知道Angular中是否有一种简单的方法可以使用ng-repeat逻辑而不是or在特定列上使用and过滤表格。现在,我的过滤器正在搜索表格中的所有内容(10列数据),当它真的只需要过滤2列数据(ID和名称)时。

我已设法将其缩小,仅在过滤(by using an object in the filter expression as per the docs并查看this SO answer)时仅查看这两列,但它使用and逻辑,这太具体了。我想让它使用or逻辑,但遇到了麻烦。

我的HTML

<input type="text" ng-model="filterText" />
<table>
      <tr ng-repeat="item in data"><td>{{ item.id }}</td><td>{{ item.name }}</td>...</tr>
</table>

我的过滤逻辑:

$filter('filter')(data, {id:$scope.filterText, name:$scope.filterText})

过滤有效,但同样,它是匹配列的交集,而不是联合。谢谢!

8 个答案:

答案 0 :(得分:23)

创建自定义过滤器并不难,您可以根据需要使用多个参数。下面是一个带有一个和两个参数的过滤器示例,但您可以根据需要添加任意数量。

示例JS:

var app = angular.module('myApp',[]);
app.filter('myTableFilter', function(){
  // Just add arguments to your HTML separated by :
  // And add them as parameters here, for example:
  // return function(dataArray, searchTerm, argumentTwo, argumentThree) {
  return function(dataArray, searchTerm) {
      // If no array is given, exit.
      if (!dataArray) {
          return;
      }
      // If no search term exists, return the array unfiltered.
      else if (!searchTerm) {
          return dataArray;
      }
      // Otherwise, continue.
      else {
           // Convert filter text to lower case.
           var term = searchTerm.toLowerCase();
           // Return the array and filter it by looking for any occurrences of the search term in each items id or name. 
           return dataArray.filter(function(item){
              var termInId = item.id.toLowerCase().indexOf(term) > -1;
              var termInName = item.name.toLowerCase().indexOf(term) > -1;
              return termInId || termInName;
           });
      } 
  }    
});

然后在你的HTML中:

<tr ng-repeat="item in data | myTableFilter:filterText">

或者如果你想使用多个参数:

<tr ng-repeat="item in data | myTableFilter:filterText:argumentTwo:argumentThree">

答案 1 :(得分:20)

使用它来搜索所有列(可能很慢):搜索。$ AngularJS API: filter

Any Column Search:
<input ng-model="search.$"> 
<table>
<tr ng-repeat="friendObj in friends | filter:search:strict">
...

答案 2 :(得分:6)

要扩展 @charlietfl 的优秀答案,这里有一个自定义过滤器,它按一列(属性)过滤,动态传递给函数而不是硬编码。这将允许您在不同的表中使用过滤器。

var app=angular.module('myApp',[]);        
app.filter('filterByProperty', function () {
        /* array is first argument, each addiitonal argument is prefixed by a ":" in filter markup*/
        return function (dataArray, searchTerm, propertyName) {
            if (!dataArray) return;
            /* when term is cleared, return full array*/
            if (!searchTerm) {
                return dataArray
            } else {
                /* otherwise filter the array */
                var term = searchTerm.toLowerCase();
                return dataArray.filter(function (item) {
                    return item[propertyName].toLowerCase().indexOf(term) > -1;
                });
            }
        }
    });

现在在加价方面

<input type="text" ng-model="filterText" />

<table>
  <tr ng-repeat="item in data |filterByProperty:filterText:'name'"><td>{{ item.id }}</td><td>{{ item.name }}</td>...</tr>
</table>

答案 3 :(得分:3)

我想通了 - 我必须编写自己的自定义过滤器。这是我的解决方案:

var filteredData;

filteredData = $filter('filter')(data, function(data) {
  if ($scope.filter) {
    return data.id.toString().indexOf($scope.filter) > -1 || data.name.toString().indexOf($scope.filter) > -1;
  } else {
    return true;
  }
});

答案 4 :(得分:1)

我创建了此过滤器以在多个字段中执行搜索:

var find = function () {
    return function (items,array) {
        var model  = array.model;
        var fields = array.fields;
        var clearOnEmpty = array.clearOnEmpty || false;
        var filtered = [];

        var inFields = function(row,query) {
            var finded = false;
            for ( var i in fields ) {
                var field = row[fields[i]];
                if ( field != undefined ) {
                    finded = angular.lowercase(row[fields[i]]).indexOf(query || '') !== -1;
                }
                if ( finded ) break;
            }
            return finded;
        };

        if ( clearOnEmpty && model == "" ) return filtered;

        for (var i in items) {
            var row = items[i];                
            var query = angular.lowercase(model);

            if (query.indexOf(" ") > 0) {
                var query_array = query.split(" ");
                var x;
                for (x in query_array) {
                    query = query_array[x];
                    var search_result = true;
                    if ( !inFields(row,query) ) {
                        search_result = false;
                        break;
                    }
                }
            } else {
                search_result = inFields(row,query);
            }                
            if ( search_result ) {
                filtered.push(row);
            }
        }
        return filtered;
    };
};   

使用方法:

<tr repeat="item in colletion
                    | find: {
                        model : model, // Input model
                        fields : [     // Array of fields to filter
                            'FIELD1',
                            'FIELD2',
                            'FIELD3'
                        ],
                        clearOnEmpty: true // Clear rows on empty model (not obligatory)
                    } "></tr>

答案 5 :(得分:0)

轻松我们可以做这种类型根据您编写的代码将轻松创建另一个字段过滤器....

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

myApp.filter('myfilter',myfilter);

function myfilter(){
   return function (items, filters) {
        
        if (filters == null) {
            return items;
        }

        var filtered = [];
        //Apply filter
        angular.forEach(items, function (item) { 
            if ((filters.Name == '' || angular.lowercase(item.Name).indexOf(angular.lowercase(filters.Name)) >= 0) 
               )
            {
                filtered.push(item);
            }

        });
        return filtered;
    };
}

myApp.controller('mycontroller',['$scope',function($scope){
  $scope.filters={Name:'',MathsMarks:''};
  $scope.students=[];
  var i=0;
  for(i=0;i<5;i++){
    var item={Name:'',Marks:[]};
  
    item.Name='student' + i;  
    item.Marks.push({Maths:50-i,Science:50 +i});
    
    $scope.students.push(item);
  }

}]);
<html ng-app='myApp'>
  <head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
</head>
  <body ng-controller='mycontroller'>
    <input type='text' name='studentName' ng-model="filters.Name" placeholder='Enter Student Name'>
    <div ng-repeat="student in students | myfilter: filters">
      Name : {{student.Name}} Marks == >
      <span ng-repeat="m in student.Marks">Maths:{{m.Maths}} Science:{{m.Science}}</span>
      </div>
  </body>
</html>

答案 6 :(得分:0)

这是我的解决方案,它非常懒,它将在第一级搜索数组中的所有字符串,你可以更新它以反复下去树,但这应该足够好......

document.body.addEventListener("keydown", function(e){
    e.preventDefault();
    keys[e.keyCode] = true; 
});
document.body.addEventListener("keyup", function(e){
    e.preventDefault();
    keys[e.keyCode] = false;    
});

答案 7 :(得分:0)