452

我有一个包含许多对象(JSON 格式)的数据数组。可以假定以下内容为该数组的内容:

var data = [
  {
    "name": "Jim",
    "age" : 25
  },
  {
    "name": "Jerry",
    "age": 27
  }
];

现在,我将这些详细信息显示为:

<div ng-repeat="person in data | filter: query">
</div

在这里,查询被建模为一个输入字段,用户可以在其中限制显示的数据。

现在,我有另一个位置显示当前显示的人数/人数,即Showing {{data.length}} Persons

我想要做的是,当用户搜索一个人并根据查询过滤显示的数据时,Showing...persons也会改变当前显示的人的值。但它没有发生。它始终显示数据中的总人数而不是过滤后的人数 - 我如何获得过滤数据的计数?

4

8 回答 8

757

对于 Angular 1.3+(感谢 @Tom)

使用别名表达式(文档:Angular 1.3.0:ngRepeat,向下滚动到参数部分):

<div ng-repeat="person in data | filter:query as filtered">
</div>

对于 1.3 之前的 Angular

将结果分配给一个新变量(例如filtered)并访问它:

<div ng-repeat="person in filtered = (data | filter: query)">
</div>

显示结果数:

Showing {{filtered.length}} Persons

摆弄一个类似的例子。归功于Pawel Kozlowski

于 2013-10-22T12:11:55.780 回答
337

为了完整起见,除了以前的答案(在控制器内执行可见人的计算)之外,您还可以在 HTML 模板中执行该计算,如下例所示。

假设您的人员列表是data可变的并且您使用模型过滤人员query,以下代码将适用于您:

<p>Number of visible people: {{(data|filter:query).length}}</p>
<p>Total number of people: {{data.length}}</p>
  • {{data.length}}- 打印总人数
  • {{(data|filter:query).length}}- 打印过滤的人数

请注意,如果您只想在页面中使用过滤数据一次,此解决方案可以正常工作。但是,如果您多次使用过滤数据,例如显示项目和显示过滤列表的长度,我建议对 AngularJS 1.3+ 使用别名表达式(如下所述)或@Wumms为 AngularJS 1.3 之前的版本提出的解决方案。

Angular 1.3 中的新功能

AngularJS 创建者也注意到了这个问题,并且在1.3 版(beta 17)中,他们添加了“别名”表达式,该表达式将在应用过滤器后存储转发器的中间结果,例如

<div ng-repeat="person in data | filter:query as results">
    <!-- template ... -->
</div>

<p>Number of visible people: {{results.length}}</p>

别名表达式将防止多个过滤器执行问题。

我希望这会有所帮助。

于 2013-03-13T11:26:30.327 回答
49

如果你有最简单的方法

<div ng-repeat="person in data | filter: query"></div>

过滤后的数据长度

<div>{{ (data | filter: query).length }}</div>
于 2016-01-19T13:25:38.137 回答
36

ngRepeat 在应用过滤器时会创建数组的副本,因此您不能使用源数组来仅引用过滤后的元素。

$filter在您的情况下,使用该服务在控制器内部应用过滤器可能会更好:

function MainCtrl( $scope, filterFilter ) {
  // ...

  $scope.filteredData = myNormalData;

  $scope.$watch( 'myInputModel', function ( val ) {
    $scope.filteredData = filterFilter( myNormalData, val );
  });

  // ...
}

然后您filteredData在视图中使用该属性。这是一个工作 Plunker:http ://plnkr.co/edit/7c1l24rPkuKPOS5o2qtx?p=preview

于 2013-03-09T22:03:51.070 回答
29

从 AngularJS 1.3 开始,您可以使用别名:

item in items | filter:x as results

在某处:

<span>Total {{results.length}} result(s).</span>

来自文档

您还可以提供一个可选的别名表达式,然后在应用过滤器后存储转发器的中间结果。通常,这用于在转发器上的过滤器处于活动状态时呈现特殊消息,但过滤后的结果集为空。

例如:项目中的项目 | filter:x as results 将重复项的片段存储为结果,但仅在项已通过过滤器处理之后。

于 2014-08-03T12:04:32.110 回答
25

还需要注意的是,您可以通过对过滤器进行分组来存储多个级别的结果

all items: {{items.length}}
filtered items: {{filteredItems.length}}
limited and filtered items: {{limitedAndFilteredItems.length}}
<div ng-repeat="item in limitedAndFilteredItems = (filteredItems = (items | filter:search) | limitTo:25)">...</div>

这是一个演示小提琴

于 2015-04-22T17:36:50.270 回答
13

这是工作示例请参阅 Plunker

  <body ng-controller="MainCtrl">
    <input ng-model="search" type="text">
    <br>
    Showing {{data.length}} Persons; <br>
    Filtered {{counted}}
    <ul>
      <li ng-repeat="person in data | filter:search">
        {{person.name}}
      </li>
    </ul>
  </body>

<script> 
var app = angular.module('angularjs-starter', [])

app.controller('MainCtrl', function($scope, $filter) {
  $scope.data = [
    {
      "name": "Jim", "age" : 21
    }, {
      "name": "Jerry", "age": 26
    }, {
      "name": "Alex",  "age" : 25
    }, {
      "name": "Max", "age": 22
    }
  ];

  $scope.counted = $scope.data.length; 
  $scope.$watch("search", function(query){
    $scope.counted = $filter("filter")($scope.data, query).length;
  });
});

于 2013-03-09T23:52:50.870 回答
10

你可以用2 种方法来做到这一点。在模板Controller中。在模板中,您可以将过滤后的数组设置为另一个变量,然后根据需要使用它。这是如何做到的:

<ul>
  <li data-ng-repeat="user in usersList = (users | gender:filterGender)" data-ng-bind="user.name"></li>
</ul>
 ....
<span>{{ usersList.length | number }}</span>

如果您需要示例,请参阅AngularJs 过滤计数示例/演示

于 2016-05-18T17:37:53.103 回答