如何在 AngularJs 中使用 ng-repeat 过滤(键、值)?

Posted

技术标签:

【中文标题】如何在 AngularJs 中使用 ng-repeat 过滤(键、值)?【英文标题】:How to filter (key, value) with ng-repeat in AngularJs? 【发布时间】:2013-01-25 04:02:13 【问题描述】:

我正在尝试做类似的事情:

<div ng-controller="TestCtrl">
    <div ng-repeat="(k,v) in items | filter:hasSecurityId">
        k v.pos
    </div>
</div>

AngularJs 部分:

function TestCtrl($scope) 

    $scope.items = 
                     'A2F0C7':'secId':'12345', 'pos':'a20',
                     'C8B3D1':'pos':'b10'
                   ;

    $scope.hasSecurityId = function(k,v)
    
       return v.hasOwnProperty('secId');
    

但不知何故,它向我显示了所有项目。如何过滤(键,值)?

【问题讨论】:

请提供一些示例数据项。或者给我们一个小提琴;) 这不是你创建过滤器的方式看documentations,正如罗宾所说,请举个例子。 我已经给出了一个完整的例子,并且我知道如何使用过滤器。我只是在问“如何将过滤器与(键,值)一起使用”。 索引和计数应该在该范围 iirc 中可用 【参考方案1】:

Angular filters 只能应用于数组而不是对象,来自 Angular 的 API -

“从数组中选择项目的子集并将其作为新数组返回。”

您有两种选择: 1) 将 $scope.items 移动到数组或 - 2) 预过滤ng-repeat 项,如下所示:

<div ng-repeat="(k,v) in filterSecId(items)">
    k v.pos
</div>

在控制器上:

$scope.filterSecId = function(items) 
    var result = ;
    angular.forEach(items, function(value, key) 
        if (!value.hasOwnProperty('secId')) 
            result[key] = value;
        
    );
    return result;

jsfiddle:http://jsfiddle.net/bmleite/WA2BE/

【讨论】:

需要小心使用这种方法以避免无限(摘要)循环。请参阅 6054 和 705。 Narretz 总结:简而言之,在 ng-repeat 中使用函数返回集合是一种反模式。最好将集合分配给范围属性,然后循环。 有用的评论。这让我陷入了循环;我希望能够过滤 any 可迭代。非常感谢。 :) 注意:现在这是一个 perf 反模式。 Angular 1.3 现在有无状态过滤器 (egghead.io/lessons/…) 所以你肯定想为此创建一个过滤器。 @kentcdodds 不要发布不免费的链接! 为什么不在重复的元素上添加一个 ng-if?【参考方案2】:

我的解决方案是创建自定义过滤器并使用它:

app.filter('with', function() 
  return function(items, field) 
        var result = ;
        angular.forEach(items, function(value, key) 
            if (!value.hasOwnProperty(field)) 
                result[key] = value;
            
        );
        return result;
    ;
);

html 中:

 <div ng-repeat="(k,v) in items | with:'secId'">
        k v.pos
 </div>

【讨论】:

但是,它会循环 n*n 次。【参考方案3】:

或者干脆使用

ng-show="v.hasOwnProperty('secId')"

在此处查看更新的解决方案:

http://jsfiddle.net/RFontana/WA2BE/93/

【讨论】:

谢谢.. 我用这个但是用ng-if 代替【参考方案4】:

您可以简单地使用angular.filter 模块,然后您甚至可以按嵌套属性进行过滤。 请参阅:jsbin2 个示例:

JS:

angular.module('app', ['angular.filter'])
  .controller('MainCtrl', function($scope) 
  //your example data
  $scope.items =  
    'A2F0C7': secId:'12345', pos:'a20' ,
    'C8B3D1': pos:'b10' 
  ;
  //more advantage example
  $scope.nestedItems =  
    'A2F0C7':
      details:  secId:'12345', pos:'a20' 
    ,
    'C8B3D1':
      details:  pos:'a20' 
    ,
    'F5B3R1':  secId:'12345', pos:'a20' 
  ;
);

HTML:

  <b>Example1:</b>
  <p ng-repeat="item in items | toArray: true | pick: 'secId'">
     item.$key ,  item 
  </p>

  <b>Example2:</b>
  <p ng-repeat="item in nestedItems | toArray: true | pick: 'secId || details.secId' ">
     item.$key ,  item 
  </p> 

【讨论】:

您应该披露angular.filter 不是核心角度模块,您是它的作者。 toArray 过滤器似乎不再存在。是否有替代品,因为filter 过滤器仍然不允许对象?【参考方案5】:

您也可以将ng-repeatng-if 一起使用:

<div ng-repeat="(key, value) in order" ng-if="value > 0">

【讨论】:

聪明。这节省了很多时间。【参考方案6】:

有点晚了,但我找了一个类似的过滤器,最后用了这样的东西:

<div ng-controller="TestCtrl">
 <div ng-repeat="(k,v) in items | filter:secId: '!!'">
   k v.pos
 </div>
</div>

【讨论】:

你是如何让它工作的?当我使用带有 ng-repeated 对象的过滤器时,我收到一个错误,这是 Angular 文档所预期的。【参考方案7】:

我已经在多个项目中使用了更多的通用过滤器:

object = 需要过滤的对象 field = 我们将过滤的对象中的字段 filter = 需要匹配字段的过滤器的值

HTML:

<input ng-model="customerNameFilter" />
<div ng-repeat="(key, value) in filter(customers, 'customerName', customerNameFilter" >
   <p>Number: value.customerNo</p>
   <p>Name: value.customerName</p>
</div>

JS:

  $scope.filter = function(object, field, filter) 
    if (!object) return ;
    if (!filter) return object;

    var filteredObject = ;
    Object.keys(object).forEach(function(key) 
      if (object[key][field] === filter) 
        filteredObject[key] = object[key];
      
    );

    return filteredObject;
  ;

【讨论】:

【参考方案8】:

虽然这个问题比较老了,但我还是想为 angular 1 开发人员分享我的解决方案。重点是重用原始角度滤镜,但透明地将任何对象作为数组传递。

app.filter('objectFilter', function ($filter) 
    return function (items, searchToken) 
        // use the original input
        var subject = items;

        if (typeof(items) == 'object' && !Array.isArray(items)) 
            // or use a wrapper array, if we have an object
            subject = [];

            for (var i in items) 
                subject.push(items[i]);
            
        

        // finally, apply the original angular filter
        return $filter('filter')(subject, searchToken);
    
);

像这样使用它:

<div>
    <input ng-model="search" />
</div>
<div ng-repeat="item in test | objectFilter : search">
    item | json
</div>

这是plunker

【讨论】:

以上是关于如何在 AngularJs 中使用 ng-repeat 过滤(键、值)?的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS + JQuery:如何在 angularjs 中获取动态内容

如何在 AngularJS 中使用 HTTPS?

如何使用 angularjs 在 RESTful 请求中执行授权?

如何在 AngularJS 中收听 jQuery 事件

如何在 AngularJS 中使用图像作为背景?

如何在 ngClass 中使用 AngularJS 过滤器?