web-dev-qa-db-fra.com

Comment obtenir la taille d'un ensemble filtré (canalisé) en angular2

J'ai écrit mon propre tube de filtre car il a disparu en angular2:

import {Pipe, PipeTransform} from 'angular2/core';

@Pipe({
  name: 'myFilter'
})
export class MyFilter implements PipeTransform {
  transform(customerData: Array<Object>, args: any[]) {
    if (customerData == undefined) {
      return;
    }
    var re = new RegExp(args[0]);
    return customerData.filter((item) => re.test(item.customerId));
  }
}

Et utilisez-le dans mon modèle:

<tr *ngFor="#singleCustomerData of customerData | myFilter:searchTerm">
  ...
</tr>

Maintenant, j'aimerais voir combien de correspondances les retours de pipe. Donc, essentiellement la taille du tableau retourné.

Dans angular 1.x, nous avons donc pu affecter l'ensemble renvoyé à une variable dans un modèle comme ceci:

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

Mais nous ne pouvons plus affecter de variables dans les modèles dans angular2.

Alors, comment puis-je obtenir la taille de l'ensemble filtré sans appeler le filtre deux fois?

23
neric

original

AFAIK il n'y a actuellement aucun moyen de le faire directement. Un hack serait d'ajouter une variable de modèle au contenu et d'utiliser une requête ViewChildren(...) pour obtenir les éléments créés et les compter.

<tr *ngFor="let singleCustomerData of customerData | myFilter:searchTerm" #someVar>
  ...
</tr>
<div>count: {{filteredItems?.length}}</div>
@ViewChildren('someVar') filteredItems;

Une approche alternative serait de passer une référence à une variable de compteur au tuyau comme indiqué dans https://plnkr.co/edit/Eqjyt4qdnXezyFvCcGAL?p=preview

mise à jour (Angular> = 4.0.0)

Depuis Angular 4*ngFor prend en charge as

<tr *ngFor="let singleCustomerData of customerData | myFilter:searchTerm as result">

que vous pouvez utiliser dans le modèle (à l'intérieur de l'élément *ngFor est ajouté à) comme

  <div>{{result?.length}}</div>
22
Günter Zöchbauer

Vous devez toujours appeler le filtre une deuxième fois mais vous pouvez l'utiliser directement comme ceci:

{{ (customerData | myFilter:searchTerm)?.length }}
21
A. Morel

Je ne sais pas exactement ce que vous voulez faire avec la taille et la solution de Günter peut répondre à vos besoins.

Cela dit, vous pouvez injecter l'instance de composant dans votre tuyau et définir directement la longueur dans une propriété de ce composant.

@Pipe({
  name: 'dump'
})
export class DumpPipe {
  constructor(@Inject(forwardRef(() => AppComponent)) app:AppComponent) {
    this.app = app;
  }

  transform(array: Array<string>, args: string): Array<string> {
    (...)
    this.app.filteredItemLength = array.length;

    return array;
  }
}

@Component({
  (...)
})
export class AppComponent {
  (...)
}

Voir cette réponse:

J'espère que ça vous aide, Thierry

4
Thierry Templier

La réponse de Gunter est dans la bonne direction, il ne manque que les informations sur la façon d'utiliser le résultat de la boucle * ngFor. Une solution possible consiste à inclure le * ngFor dans une directive plus large, comme suit:

<ng-directive *ngIf='customerData | myFilter:searchTerm as filteredItems'>
   <tr *ngFor="let singleCustomerData of filteredItems">
   ...
   </tr>
   <div>count: {{filteredItems.length}}</div>
</ng-directive>

Les crédits pour cet indice sont disponibles sur le post suivant:

https://netbasal.com/using-pipe-results-in-angular-templates-430683fa221

3
sertal70

Vous pouvez simplement passer un objet du composant classe à HTML-pipe comme deuxième argument. Et dans le tube de classe, passez le tableau résultant.

0
ktretyak