通过AngularJS中的多个特定模型属性进行过滤(OR关系)

时间:2012-11-04 04:36:53

标签: angularjs

看一下这里的示例:http://docs.angularjs.org/api/ng.filter:filter

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

假设我有一个带有“名称”属性,“手机”属性和“秘密”属性的模型,我将如何通过 “名称”和“电话“属性和”秘密“属性?因此,从本质上讲,用户可以键入姓名或电话号码,ng-repeat将正确过滤,但即使用户键入的值等于“秘密”值的一部分,也不会返回任何内容。

感谢。

13 个答案:

答案 0 :(得分:168)

以下是plunker

New plunker with cleaner code & where both the query and search list items are case insensitive

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

来自official doc

  

function:谓词函数可用于写入任意过滤器。   为数组的每个元素调用该函数。最终的结果是   谓词返回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;
};

<强>更新

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

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

详细信息post显示了如何执行此操作。

简而言之,我们将ng-change添加到输入中以监控新的搜索更改

然后触发过滤功能。

答案 1 :(得分:76)

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

<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发布。

答案 2 :(得分: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;
    };

答案 3 :(得分:5)

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

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

collection | filterBy: [prop, nested.prop, etc..]: search

答案 4 :(得分:3)

希望这个答案有所帮助,Multiple Value Filter

这个fiddle

中的工作示例
arrayOfObjectswithKeys | filterMultiple:{key1:['value1','value2','value3',...etc],key2:'value4',key3:[value5,value6,...etc]}

答案 5 :(得分:2)

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

问题的例子:

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

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

<div ng-repeat="member in people | filter: searchString">

答案 6 :(得分:1)

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

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

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

lst <- mget(ls(pattern='total\\d+'))

classify_cnv = function (column)
  ifelse(column < 2, 1, ifelse(column > 2, 3, 2))

classify_all_cnvs = function (df) {
  df$CopyNumber.x = classify_cnv(df$CopyNumber.x)
  df$CopyNumber.y = classify_cnv(df$CopyNumber.y)
  df
}
result = lapply(lst, classify_all_cnvs)

more<-lapply(result, function(kv){
kappa2(kv[,c(5,8)], "squared")})

答案 7 :(得分:1)

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

})();

答案 8 :(得分:0)

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

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

答案 9 :(得分: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>

答案 10 :(得分:0)

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

ng-repeat= 'item in list | filter :{property:value}'

答案 11 :(得分: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中的属性

答案 12 :(得分:0)

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

x <- c("mmu-let-7a3",
"mmu-miR-19b1",
"mmu-miR-548d2",
"mmu-miR-450a1")