web-dev-qa-db-fra.com

Angular 2+ - vérifie si Pipe renvoie un sous-ensemble vide de la liste d'origine

J'ai une liste de chaînes que je veux parcourir, mais je veux pouvoir les filtrer en utilisant un terme de recherche. Comme ça:

<div *ngFor="#item in list | search: searchTerm">{{ item }}</div>

Ma question est la suivante: comment puis-je vérifier si le canal renvoie un sous-ensemble vide de la liste? 

En d'autres termes, si aucune des chaînes ne correspond au terme recherché, je souhaite afficher un message disant: "Aucune correspondance".

<div *ngIf="(list | search: searchTerm).length === 0">
  "No matches"
</div>
<div *ngFor="#item in list | search: searchTerm">{{ item }}</div>

Vous pouvez également modifier votre canal pour renvoyer un jeton spécifique indiquant que la liste est vide.

@Pipe({
  name: 'search'
})
export class SearchPipe {

  transform(value, searchTerm) {
    let result = ...
    if(result.length === 0) {
      return [-1];
    }
    return result;
  }
}
<ng-container *ngFor="let item of list | search: searchTerm">
  <div *ngIf="item === -1">"No matches"</div>
  <div *ngIf="item !== -1">{{ item }}</div>
</ng-container>
46

Une autre méthode consiste à vérifier l’élément html pour les enfants ou, dans mon cas, le tableau pour les lignes. 

<table #myTable>
  <tr *ngFor="let item of list | somePipe : searchText">
      <td>{{ item.name }}</td>
  </tr>
</table>

<p *ngIf="!myTable.rows.length">No results</p>
7
Boban Stojanovski

Il est possible de tirer parti de l'injection de dépendance dans les canalisations. Vous pouvez injecter le composant:

Ensuite, vous pouvez définir une propriété pour notifier ceci:

@Pipe({
  name: 'search'
})
export class SearchPipe {
  constructor(@Inject(forwardRef(() => SomeComponent)) private comp:SomeComponent) {

  }

  transform(value) {
    var filtered = value.map((v) => v-1);
    this.comp.isEmpty = (filtered.length === 0);
    return filtered;
  }
}

Le principal inconvénient est que vous liez le tuyau au sein du composant. L'avantage est que le filtrage est exécuté une fois.

5

Ceci est mon code qui modifie un peu de @ Günter Zöchbauer

<div  *ngFor="let filter_list of list | FilterItem" >
    <div *ngIf=" filter_list == -1 " class="alert alert-info">No item found</div>    
    <div *ngIf="filter_list !== -1" *ngFor="let item of filter_list  ; let i = index;" >
        {{ item }}
    </div>
</div>

Code de tuyau

@Pipe({
  name: 'FilterItem'
})
export class FilterItem {

  transform(list, args?) {
       let result = ...; 
       if ( result && result.length > 0 ){
          return [ result ];
       }else{
          return [ -1 ];
       }
  }
}
4
Tuan Bach Van

Si votre objectif est simplement de rendre un élément que vous ne le feriez avec une requête CSS, je suis simplement en train de jauger Günter Zöchbauer code.

<ng-container *ngFor="let item of list | search: searchTerm">
  <div *ngIf="item !== -1">{{ item }}</div>
  <div class="empty">"No matches"</div>
</ng-container>

CSS

div.empty {
  display:none;
}
div.empty:first-child {
  display:block;
}

.list div.empty {
  display: none;
}

.list div.empty:first-child {
  display: block;
}
<h4>If you hava record to display than</h4>
<div class="list">
  <div>The first record.</div>
  <div>The second record.</div>
  <div>The third record.</div>
  <div class="empty">"No matches"</div>
</div>
<br>
<h4>If no record to show</h4>
<div class="list">
  <div class="empty">"No matches"</div>
</div>

1
Naveen raj

C'est la solution la plus propre que j'ai pu produire.

@Pipe({
  name: 'search'
})
export class SearchPipe {

  transform(value, searchTerm) {
    let result = ...
    if(result.length === 0) {
      return [undefined];
    }
    return result;
  }
}

En retournant [undefined], les contrôles dans le DOM sont beaucoup plus propres et plus faciles à lire.

<ng-container *ngFor="let item of list | search: searchTerm">
  <div *ngIf="!item">"No matches"</div>
  <div *ngIf="item">{{ item }}</div>
</ng-container>
0

Avec angular prenant maintenant en charge ngIf avec des variables, vous pouvez affecter le résultat du tuyau à une nouvelle variable, puis effectuer la boucle dans le bloc if.

<ng-container *ngIf="search: searchTerm as results; else noItems">
 <!-- else is for cases where search:Search term is undefined or null  -->

    <div *ngFor="let item of results">{{item}}</div>

    <!-- the case where the pipe returns an empty array  -->
    <div *ngIf="!result.length">no items match the search</div>
</ng-container>
<ng-template #noItems>searching...</ng-template>
0
Nithish Thomas