使用AngularJS中的单个输入过滤多个字段

时间:2014-01-07 17:10:55

标签: angularjs angularjs-filter

我有一个JSON对象,如下所示

[{
    "id": 1,
    "firstName": "Jennifer",
    "middleName": null,
    "lastName": "Aniston",
    "address": "New York City",
}, {
    "id": 2,
    "firstName": "Angelina",
    "middleName": null,
    "lastName": "Jolie",
    "address": "Beverley Hills",
}, {
    "id": 3,
    "firstName": "Emma",
    "middleName": null,
    "lastName": "Watson",
    "address": "London",
}]

我正在使用ng-repeat在视图中填充此数据。

<td ng-repeat="row in list | filter:filterBeauties">
{{row.firstName}} {{row.lastName}}
</td>

现在我有一个输入框,我想用它来过滤这些名称。我想使用相同的输入框来过滤firstName然后过滤lastName而不过滤其他任何东西(例如地址)。

<input type="text" placeholder="Filter" ng-model="filterBeauties.firstName">

任何想法我怎样才能实现它?

5 个答案:

答案 0 :(得分:6)

试试这个fiddle

基本上,我创建了一个子结构,用于在显示的数据结构中进行过滤,并仅对该属性进行过滤(例如&#39; filterTerms&#39;):

HTML:

<div ng-controller="MyCtrl">
   <input type="text" ng-model="search.filterTerms">
   <table border="1">
      <tr ng-repeat="row in list | filter:search">
         <td>{{row.firstName}} {{row.lastName}}</td>
      </tr>
   </table>
</div>

JavaScript的:

var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.list = [{
    "id": 1,
    "address": "New York City",
    "firstName": "Jennifer",
    "middleName": null,
    "lastName": "Aniston",
    "filterTerms": {
        "firstName": "Jennifer",
        "middleName": null,
        "lastName": "Aniston",
    }
}, {
    "id": 1,
    "address": "New York City",
    "firstName": "Jennifer",
    "middleName": null,
    "lastName": "Leela",
    "filterTerms": {
        "firstName": "Jennifer",
        "middleName": null,
        "lastName": "Leela",            
    }
}, {
    "id": 2,
    "address": "Beverley Hills",
    "firstName": "Angelina",
    "middleName": null,
    "lastName": "Jolie",
    "filterTerms": {
        "firstName": "Angelina",
        "middleName": null,
        "lastName": "Jolie",            
    }
}, {
    "id": 3,
    "address": "London",
    "firstName": "Emma",
    "middleName": null,
    "lastName": "Watson",
    "filterTerms": {
        "firstName": "Emma",
        "middleName": null,
        "lastName": "Watson",            
    }
}];
}

通过将所有名称放在一个字段中,您可以进一步简化此操作(请参阅小提琴here

HTML:

<div ng-controller="MyCtrl">
    <input type="text" ng-model="search.filterTerm" />
    <table border="1">
        <tr ng-repeat="row in list | filter:search">
            <td>{{row.first}} {{row.last}} {{row.address}}</td>
        </tr>
    </table>
</div>

JavaScript的:

var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
    $scope.list = [{
        "id": 0, "first": "Jenny", "last": "Sorenson", "address": "123 W. Wallnut St.",
        "filterTerm": "Jenny Sorenson"
    },{
        "id": 0, "first": "Susan", "last": "Hinkle", "address": "456 W. Doorbell Dr.",
        "filterTerm": "Susan Hinkle"
    },{
        "id": 0, "first": "Rachel", "last": "Karlyle", "address": "789 W. Sunset Blvd.",
        "filterTerm": "Rachel Karlyle"
    },{
        "id": 0, "first": "Gwen", "last": "Lippi", "address": "0 W. Silly Cir.",
        "filterTerm": "Gwen Lippi"
    }]
}

答案 1 :(得分:6)

考虑到您的用户拥有此表单:

{
  "id": 2,
  "firstName": "Angelina",
  "middleName": null,
  "lastName": "Jolie",
  "address": "Beverley Hills"
}

如果你想用你的名字,姓氏或两者同时搜索你的一个用户,你需要将它们连在一起。

$scope.query = '';

$scope.search = function (user) {
  var query = $scope.query.toLowerCase(),
  fullname = user.firstName.toLowerCase() + ' ' + user.lastName.toLowerCase();

  if (fullname.indexOf(query) != -1) {
    return true;
  }
  return false;
};

如果当前用户满足您的查询,此函数将返回true,如果不满足,则返回false。在函数内部,我建议将您的查询放在小写中,这样您就不必处理用户将在搜索输入中输入的大写字母。

这是HTML:

<input type="text" placeholder="Search" ng-model="query">
<table>
   <tr ng-repeat="user in users | filter:search">
      <td>{{user.firstName}} {{user.lastName}}</td>
   </tr>
</table>

此技术仅在您尝试搜索Angelina JolieAngelinaJolie甚至InA JOLIe时才会生效(毕竟为什么不会)。如果您尝试首先搜索Jolie Angelina这样的姓氏,则无效。您可以通过在函数中创建第二个全名来轻松修复它(例如reverseFullname),先在lastName中连接,然后在firstName中连接,然后像第一个全名字符串一样对其进行测试。

答案 2 :(得分:4)

好的,这就是我解决它的方法。

我在json对象中添加了一个新项目(使用angular.forEach函数)并按其过滤。

$scope.list = beauties.query(function(response) {
    angular.forEach(response, function(value, key) {
          var fullName = value.firstName + ' ' + value.lastName;
          $scope.list[key].fullName = fullName;
   });
});

输入框代码:

<input type="text" placeholder="Filter" ng-model="filterBeauties.fullName">

纳克重复

<td ng-repeat="row in list | filter:filterBeauties">
{{row.firstName}} {{row.lastName}}
</td>

答案 3 :(得分:3)

您可以将第三个参数传递给过滤器函数:

$filter('filter')(list, {'firstName':search});

我会做类似下面的事情:

<input type="text" ng-model="search">
<table border="1">
    <tr ng-repeat="row in list | filterBoth:search">
        <td>{{row.firstName}} {{row.lastName}}</td>
    </tr>
</table>

然后将自定义过滤器编写为:

myApp.filter('filterBoth', function($filter) {
  return function(list, search) {
    if (!search) return list;

    var arrSearch = search.split(' '),
        lookup = '',
        result = [];

    arrSearch.forEach(function(item) {
      lookup = $filter('filter')(list, {'firstName': item});console.log(lookup);
      if (lookup.length > 0) result = result.concat(lookup);
    });

    return result;
  };
});

演示:http://jsfiddle.net/wAp4S/1/

唯一的问题是,当您连接两个类似的数组时,您将获得重复的行,这些数组可以使用_.uniq underscore.js方法轻松修复。

答案 4 :(得分:2)

尝试angular-filter库,而不是编写复杂过滤器searchField过滤器在此处非常有用。

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

<强> CONTROLLER

$scope.users = [
  { first_name: 'Sharon', last_name: 'Melendez' },
  { first_name: 'Edmundo', last_name: 'Hepler' },
  { first_name: 'Marsha', last_name: 'Letourneau' }
];

<强> HTML

<input ng-model="search" placeholder="search by full name"/>
<th ng-repeat="user in users | searchField: 'first_name': 'last_name' | filter: search">
  {{ user.first_name }} {{ user.last_name }}
</th>
<!-- so now you can search by full name -->

祝你好运。