Angularjs过滤,如果有任何输入匹配

时间:2016-02-18 04:25:06

标签: angularjs

我有三个输入框,我想从中搜索。

<input type="text" ng-model="firstName" />
<input type="text" ng-model="lastName" />
<input type="text" ng-model="occupation" />

数据传递给控制器​​,我的表已构建。

<table>
  <tbody>
   <tr ng-repeat="person in persons | filter: firstName 
        | filter: lastName | filter: Company">"
     <td>
      {{person.FirstName}}
     </td>
     <td>
      {{person.LastName}}
     </td>
     <td>
      {{person.Occupation}}
     </td>

如果任何输入产生匹配,我将无法过滤。目前,所有输入必须匹配才能显示表项。

例如,我的表(FirstName LastName Occupation):

Bob Dylan Singer

Justin Timberlake歌手

乔治卢卡斯电影制片人

我的意见:George Doe Singer

这应该显示列表中的所有三个,因为George和Singer是匹配。

2 个答案:

答案 0 :(得分:1)

您可以使用OR条件创建自己的自定义过滤器,而不是使用AND条件。

例如,在视图中添加对新过滤器的引用:

<强> HTML

<table>
    <tbody>
    <tr ng-repeat="person in persons | filter: personFilter">"
    <td>
      {{person.FirstName}}
    </td>
    <td>
      {{person.LastName}}
     </td>
    <td>
      {{person.Occupation}}
    </td>

然后在控制器中(或单独的过滤器对象),添加新过滤器所需的条件

<强>控制器

$scope.personFilter = function (person) {
    return ((person.firstName.toLowerCase().indexOf($scope.firstName) > -1)  || (person.lastName.toLowerCase().indexOf($scope.lastName) > -1) || (person.occupation.toLowerCase().indexOf($scope.occupation) > -1));
}

答案 1 :(得分:0)

可以实现自定义过滤器,但我不喜欢整个数组传递给过滤器函数的事实,它必须返回一个只包含你想要的元素的新数组保持。此外,我不希望必须在$scope上指定要过滤的属性,或者在自定义过滤器中对其进行硬编码。

您可以在filter:<predicate>中使用ng-repeat并使用函数调用,该函数调用本身会返回用于过滤的谓词函数,就像我在代码段(<tr ng-repeat="person in persons | filter:matchAnyProp(['firstName', 'lastName'])">)中所做的那样。这样,我可以在HTML中指定要过滤的属性,或使用$scope上指定的属性数组。此外,我也可以重复使用以匹配不同的属性。

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


app.controller('MainCtrl', ['$scope', function($scope){
  // An array to filter through
  $scope.persons = [ 
    { "firstName": "Milton", "lastName": "Erickson" },
    { "first": "Mattie", "lastName": "Thompson" },
    { "first": "Lura", "last": "Flores" },
    { "first": "Brent", "last": "Neal" },
    { "first": "Jean", "last": "Guerrero" },
    { "first": "Chester", "last": "Sims" },
    { "first": "Winnie", "last": "Potter" },
    { "firstName": "Richard", "lastName": "Obrien", "friend": "Fanny Arnold" },
    { "firstName": "Lena", "lastName": "Walsh", "friend": "Roger Lynch" },
    { "firstName": "Charlotte", "lastName": "Greer" },
    { "firstName": "Beulah", "lastName": "Logan", "friend": "Katie Singleton" },
    { "firstName": "Benjamin", "lastName": "Hodges" },
    { "first": "Bessie", "last": "Lloyd" },
    { "first": "Marie", "last": "Meyer" },
    { "firstName": "Rick", "lastName": "Sanchez" },
    { "first": "Lillie", "last": "Foster" },
    { "first": "Cynthia", "last": "Lowe" },
    { "name": "Grace", "last": "Sanchez" } 
  ];
  


    
    
  // Function which generates and returns a filter predicate
  // function that returns true or false if item contains 
  // any keys specified in "propsToMatch" argument
  $scope.matchAnyProp = function(propsToMatch){
    return (item) => Object.keys(item).reduce( (prev, curr, index, arry) => (propsToMatch.indexOf(curr) != -1) ? true : prev , false);
  };
}]);
<table ng-app="MainApp" ng-controller="MainCtrl" class='table table-bordered table-striped'>
  <thead>
    <tr>
      <th>First</th>
      <th>Last</th>
      <th>Friend</th>
    </tr>
  </thead>
  
  
  <tbody>
    <tr ng-repeat="person in persons | filter:matchAnyProp(['firstName', 'lastName'])">
      <td>{{person.firstName}}</td>
      <td>{{person.lastName}}</td>
      <td>{{person.friend}}</td>
    </tr>
  </tbody>
</table>


<link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>