web-dev-qa-db-fra.com

Comment afficher la longueur des données ng-repeat filtrées

J'ai un tableau de données qui contient de nombreux objets (format JSON). Les éléments suivants peuvent être considérés comme le contenu de ce tableau:

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

Maintenant, j'affiche ces détails comme:

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

Ici, la requête est modélisée à un champ de saisie dans lequel l'utilisateur peut restreindre les données affichées.

Maintenant, j'ai un autre emplacement dans lequel j'affiche le nombre actuel de personnes/personnes en cours d'affichage, à savoir Showing {{data.length}} Persons

Ce que je veux faire, c'est que lorsque l'utilisateur recherche une personne et que les données affichées sont filtrées en fonction de la requête, le Showing...persons change également la valeur des personnes affichées. Mais cela ne se produit pas. Il affiche toujours le nombre total de personnes dans les données plutôt que le nombre filtré - comment puis-je obtenir le nombre de données filtrées?

425
user109187

Pour Angular 1.3 + (crédits de @Tom)

Utilisez un expression alias (Docs: version angulaire 1.3.0: ngRepeat , faites défiler jusqu'à la section Arguments):

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

Pour Angular antérieure à 1.3

Affectez les résultats à une nouvelle variable (par exemple, filtered) et accédez-y:

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

Afficher le nombre de résultats:

Showing {{filtered.length}} Persons

Violon a exemple similaire . Les crédits vont à Pawel Kozlowski

733
Wumms

Par souci d'exhaustivité, en plus des réponses précédentes (calcul des personnes visibles dans le contrôleur), vous pouvez également effectuer ces calculs dans votre modèle HTML, comme dans l'exemple ci-dessous.

En supposant que votre liste de personnes soit dans la variable data et que vous filtrez les personnes à l'aide du modèle query, le code suivant fonctionnera pour vous:

<p>Number of visible people: {{(data|filter:query).length}}</p>
<p>Total number of people: {{data.length}}</p>
  • {{data.length}} - imprime le nombre total de personnes
  • {{(data|filter:query).length}} - imprime le nombre filtré de personnes

Notez que cette solution fonctionne correctement si vous souhaitez utiliser les données filtrées une seule fois dans une page. Toutefois, si vous utilisez des données filtrées plus d’une fois, par exemple, pour présenter des éléments et pour afficher la longueur de la liste filtrée, je suggérerais d'utiliser une expression alias (décrite ci-dessous) pour AngularJS 1.3 + ou la solution proposée par @ Wumms pour la version d’AngularJS antérieure à 1.3.

Nouvelle fonctionnalité dans Angular 1.3

Les créateurs d’AngularJS ont également remarqué ce problème et dans la version 1.3 (beta 17) ils ont ajouté une expression "alias" qui stockera les résultats intermédiaires du répéteur après l’application des filtres, par exemple.

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

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

L'expression alias empêchera plusieurs problèmes d'exécution du filtre.

J'espère que cela aidera.

328
Tom

Le moyen le plus simple si vous avez

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

Longueur des données filtrées

<div>{{ (data | filter: query).length }}</div>
36
ionescho

ngRepeat crée une copie du tableau lorsqu'il applique un filtre, vous ne pouvez donc pas utiliser le tableau source pour référencer uniquement les éléments filtrés.

Dans votre cas, il peut être préférable d'appliquer le filtre à l'intérieur de votre contrôleur à l'aide du service $filter :

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

  $scope.filteredData = myNormalData;

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

  // ...
}
_

Ensuite, vous utilisez plutôt la propriété filteredData dans votre vue. Voici un Plunker de travail: http://plnkr.co/edit/7c1l24rPkuKPOS5o2qtx?p=preview

34

Depuis AngularJS 1.3, vous pouvez utiliser des alias:

item in items | filter:x as results

et quelque part:

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

De docs :

Vous pouvez également fournir une expression d'alias facultative qui stockera ensuite les résultats intermédiaires du répéteur une fois les filtres appliqués. Généralement, cela est utilisé pour afficher un message spécial lorsqu'un filtre est actif sur le répéteur, mais que le jeu de résultats filtré est vide.

Par exemple: item dans items | filter: x en tant que résultats stockera le fragment des éléments répétés en tant que résultats, mais uniquement après que les éléments ont été traités par le filtre.

29
WelcomeTo

Il est également utile de noter que vous pouvez stocker plusieurs niveaux de résultats en regroupant des filtres.

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>

voici un violon de démonstration

24
JeremyWeir

Voici un exemple travaillé Voir sur 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;
  });
});
13
Maksym

Vous pouvez le faire avec 2 façons . Dans modèle et dans Contrôleur . Dans template, vous pouvez définir votre tableau filtré sur une autre variable, puis l'utiliser comme vous le souhaitez. Voici comment faire:

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

Si vous avez besoin d’exemples, reportez-vous à la section exemples/démos filtrés avec AngularJs

9