web-dev-qa-db-fra.com

filtre personnalisé dans mat-table

J'utilise mat-table. Il a un filtre qui fonctionne bien avec doc exemple:

De https://material.angular.io/components/table/overview , le code d'origine est le suivant:

    <div class="example-header">
       <mat-form-field>
         <input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter">
       </mat-form-field>
   </div>

   <mat-table #table [dataSource]="dataSource">
      <!-- the rest of the code -->
   </mat-table>
    export class TableFilteringExample {
     displayedColumns = ['position', 'name', 'weight', 'symbol'];
     dataSource = new MatTableDataSource(ELEMENT_DATA);

     applyFilter(filterValue: string) {
       filterValue = filterValue.trim(); // Remove whitespace
       filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
       this.dataSource.filter = filterValue;
     }
    }
    const ELEMENT_DATA: Element[] = [
     {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
     {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
     {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
     {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
     {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'}
    ]; 

Avec cette implémentation, lorsqu’il filtre, il filtre pour n’importe quelle colonne.

Maintenant, j'essaye de changer le filtre parce que je veux que le filtre soit juste pour la colonne "name", alors j'essaye de réécrire le filtre et d'assigner à filterData.

      applyFilter(filterValue: string) {
        filterValue = filterValue.trim(); // Remove whitespace
        filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
       this.dataSource.filteredData = this.filterByEmail(filterValue); 
        console.log(this.dataSource.filteredData); //value is what I want.
    }

    filterByName(filter: string): any {
      const dataFiltered = this.data.filter(function(item){
         return item.name.indexOf(filter) > -1
       })
        return dataFiltered;
    }

En console, je peux voir que this.dataSource.filteredData contient les données que je veux imprimer, mais table n'est pas rechargée.

Qu'est-ce qu'il me manque?

9
cucuru

J'ai trouvé la solution ici .

Il est nécessaire de réécrire filterPredicate et de l'utiliser comme d'habitude, filterPredicate doit renvoyer true lorsque le filtre passe et false s'il ne le fait pas

export interface Element {
 name: string;
 position: number;
 weight: number;
 symbol: string;
}


dataSource = new MatTableDataSource(ELEMENT_DATA);
/* configure filter */
this.dataSource.filterPredicate = 
  (data: Element, filter: string) => data.name.indexOf(filter) != -1;


applyFilter(filterValue: string) {
   filterValue = filterValue.trim(); // Remove whitespace
   filterValue = filterValue.toLowerCase(); // MatTableDataSource defaults to lowercase matches
   this.dataSource.filter = filterValue;
 }
21
cucuru

N'oubliez pas d'appliquer .trim().toLowerCase() sur vos données, sinon vous risquez d'obtenir des résultats inattendus. Voir mon exemple ci-dessous:

this.dataSource.filterPredicate = (data:
  {name: string}, filterValue: string) =>
  data.name.trim().toLowerCase().indexOf(filterValue) !== -1;

applyFilter(filterValue: string) {
    this.dataSource.filter = filterValue.trim().toLowerCase();
}
1
Loïc Gaudard