24

给定一个具有 $scope 属性的控制器,它是一个具有其他属性的对象,而不是像下面这样的数组,我应该如何过滤ng-repeat集合?

这是一个 JSFiddle:http: //jsfiddle.net/ZfGx4/110/

控制器:

function HelloCntl($scope, $filter) {
    $scope.friends = {
        john: {
            name: 'John',
            phone: '555-1276'
        },
        mary: {
            name: 'Mary',
            phone: '800-BIG-MARY'
        },
        mike: {
            name: 'Mike',
            phone: '555-4321'
        },
        adam: {
            name: 'Adam',
            phone: '555-5678'
        },
        julie: {
            name: 'Julie',
            phone: '555-8765'
        }
    };
}​

模板:

<div ng:app>
 <div ng-controller="HelloCntl">
  <input placeholder="Type to filter" ng-model="query">     
  <ul>
   <li ng-repeat="(id, friend) in friends | filter:query">
    <span>{{friend.name}} @ {{friend.phone}}</span>
   </li>
  </ul>
 </div>
</div>
4

6 回答 6

25

我会将我的数据结构更改为数组。无论如何,这是过滤您的朋友对象的另一种实现。

angular.module('filters',['utils'])
  .filter('friendFilter', function(utils){

    return function(input, query){
      if(!query) return input;
      var result = [];

      angular.forEach(input, function(friend){
        if(utils.compareStr(friend.name, query) ||
           utils.compareStr(friend.phone, query))
          result.push(friend);          
      });
      return result;
    };
  });

这仅对对象进行一次迭代,通过 and 进行比较,name并且phone可以像这样调用。

<li ng-repeat="friend in friends | friendFilter:query">

compareStr在另一个模块中定义了,但你真的不需要这样做。

angular.module('utils', [])
  .factory('utils', function(){
    return{
      compareStr: function(stra, strb){
        stra = ("" + stra).toLowerCase();
        strb = ("" + strb).toLowerCase();
        return stra.indexOf(strb) !== -1;
      }
    };
  });

不要忘记将filters模块注入您的应用程序

angular.module('app',['filters'])

这是完整的示例:http: //jsbin.com/acagag/5/edit

于 2012-12-15T04:17:38.467 回答
13

我想你不能直接用“过滤器”来做。查看 angular.js 中的代码,这些是 filter 函数的第一行:

function filterFilter() {
  return function(array, expression) {
    if (!(array instanceof Array)) return array;

因此,如果它接收到与数组不同的东西,它什么也不做。

这是一种方法,不确定我是否会推荐它,但这是一个想法:

在控制器中,只需在将其传递给过滤器之前转换为数组:

$scope.filteredFriends = function() {
    var array = [];
    for(key in $scope.friends) {
        array.push($scope.friends[key]);
    }
    return $filter('filter')(array, $scope.query);
}

和 ng 重复:

<li ng-repeat="friend in filteredFriends()">

示例:http: //jsbin.com/acagag/2/edit

也许更好的解决方案是编写自定义过滤器。

于 2012-12-15T00:51:01.910 回答
3

我遇到了同样的问题,并成功创建了自己的接受地图的过滤器,同时仍然使用内置过滤器进行实际匹配。

我的自定义过滤器遍历地图,并为每个元素调用内置过滤器,但鉴于该过滤器只接受一个数组,我将每个元素包装在一个长度为 1 的数组中(下面的 [数据])。因此,如果输出数组的长度仍为 1,则匹配成功。

.filter('mapFilter', function($filter) {
  var filter = $filter('filter');

  return function(map, expression, comparator) {
    if (! expression) return map;

    var result = {};
    angular.forEach(map, function(data, index) {
      if (filter([data], expression, comparator).length)
        result[index] = data;          
    });

    return result;
  }
})

这种设置当然会降低效率,因为需要内置过滤器来确定它需要对地图中的每个元素执行什么操作,而不是只给它一个包含所有元素的数组,而不是只给它一次,但在我的情况下,使用地图在 500 个元素中,过滤仍然是瞬时的。

于 2014-06-08T10:06:10.033 回答
1

我举了一个关于如何不将对象更改为数组的示例。我认为这更正确地回答了这个问题。

我有同样的问题,我无法在对象中搜索。

http://jsbin.com/acagag/223/edit

angular.module('filters',['utils'])
  .filter('friendFilter', function(utils){

    return function(input, query){
      if(!query) return input;
      var result = {};

      angular.forEach(input, function(friendData, friend){
        if(utils.compareStr(friend, query) ||
           utils.compareStr(friendData.phone, query))
          result[friend] = friendData;          
      });
      return result;
    };
  });

所以只是返回一个对象而不是返回一个数组。

希望这对某人有帮助!

于 2014-03-20T14:39:47.267 回答
1

不是最佳解决方案,但如果您想要快速而肮脏的东西:

<li ng-repeat="(id, friend) in friends | filter:query" ng-hide="id !== query.id">
  <span>{{friend.name}} @ {{friend.phone}}</span>
</li>

或者ng-if代替ng-hide

于 2015-02-22T21:26:32.217 回答
0

除了使用过滤器,您还可以简单地:

$http.get('api/users').success(function(data){
    angular.forEach(data, function(value, key){
        users.push(value);
    });
    $scope.users = users;
});

并且在模板中

<input type="text" ng-model="query" placeholder="Search user"/>

<li ng-repeat="user in users | filter:query">
    {{ user.name }}
</li>
于 2014-06-06T09:30:35.153 回答