【问题标题】:How to filter (key, value) with ng-repeat in AngularJs?如何在 AngularJs 中使用 ng-repeat 过滤(键、值)?
【发布时间】: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 中可用

标签: javascript angularjs frameworks ng-repeat angular-filters


【解决方案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 模块,然后您甚至可以按嵌套属性进行过滤。
请参阅:jsbin
2 个示例:

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-repeat 与ng-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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-15
      • 1970-01-01
      相关资源
      最近更新 更多