web-dev-qa-db-fra.com

Comment attacher MatPaginator à une source de données provenant du serveur dans une table de matériau angulaire?

J'utilise angular Table de matériaux pour créer une grille dans mon projet Angular 5. Mes données proviennent d'une requête http et sont affectées à une variable appelée dataSourceNew comme celle-ci dans le fichier view.ts. Ici, dataSourceNew a un contenu et une structure dynamiques et je n’exporte donc aucune interface.

      this.http.get('http://example.org?,{headers: this.headers})
          .subscribe(
          res => { 

           this.displayedColumnsNew = res.record;
           this.dataSourceNew = res.data;
           this.matdatasource = new MatTableDataSource(this.dataSourceNew);
           this.dataSourceNew.paginator = this.paginator;
           console.log("got matdatasource object",this.matdatasource);
      // attached the result of this log below

         });

Je parviens à créer une table de données en utilisant cette syntaxe dans un fichier html.

     <div class="example-container mat-elevation-z8">
           <mat-table #table [dataSource]="dataSourceNew">


       <ng-container  *ngFor="let head of tableData.record; let i= index; " matColumnDef="{{head}}" (click)="setClickedRow(ddata) "  [class.active]="ddata[primaryid] == selectedRow">
               <mat-header-cell *matHeaderCellDef> {{tableData.gridhead[i]}} 
                </mat-header-cell>
              <mat-cell *matCellDef="let element"> {{element[head]}} </mat-cell>
         </ng-container>


     <mat-header-row *matHeaderRowDef="displayedColumnsNew"></mat-header-row>
          <mat-row *matRowDef="let row; columns: displayedColumnsNew;">
        </mat-row>
            </mat-table>
     </div>

Maintenant, je veux attacher une pagination à cette table et pour cela j'ai déclaré ceci

 @ViewChild(MatPaginator) paginator: MatPaginator;

Mais quand j'attache la pagination à la table en HTML comme ceci,

  <mat-paginator #paginator
                 [pageSize]="10"
                 [pageSizeOptions]="[5, 10, 20]"
                 [showFirstLastButtons]="true">
  </mat-paginator>

J'ai eu l'erreur ci-dessous dans la console et cela casse mon application.

J'ai déjà importé ce

import {MatPaginator, MatTableDataSource} from '@angular/material';

Dans le fichier .ts respectif.

Uncaught Error: Template parse errors:
Can't bind to 'pageSize' since it isn't a known property of 'mat-paginator'.
1. If 'mat-paginator' is an Angular component and it has 'pageSize' input, then verify that it is part of this module.
2. If 'mat-paginator' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '@NgModule.schemas' of this component.

Aussi, lorsque je me connecte à this.dataSourcenew: L'élément paginator de cet objet est vide: comment utiliser le paginateur de matériau angulaire sans créer d'interface?

Mettre à jour :

Avec la suggestion de David: j'ai ajouté MatPaginator aux importations du module principal de l'application. Maintenant, le bloc de pagination montre parfaitement.

Mais les enregistrements actuels indiquent "0 sur 0". même si j'ai 14 enregistrements et que les fonctions de pagination telles que le changement d'enregistrements, next, previous etc ne fonctionnent pas. Qu'est-ce qui me manque?

Mise à jour 2: j'ai appliqué la propriété Length à des balises de pagination. Maintenant, la pagination fonctionne correctement. Le problème est que maintenant le datatable ne change pas le no actuel. de rangées.

Mise à jour 3: Selon les suggestions de Pierre Mallet, j'ai apporté les modifications nécessaires. et maintenant sans dire explicitement que le total [longueur] est déduit de la réponse de l’API. De plus, la pagination est correctement reliée à ma this.matdatasource = new MatTableDataSource([]);. Par conséquent, aucun codage explicite n’a été fait jusqu’à présent pour y parvenir.

Maintenant, je veux juste récupérer quelques enregistrements au départ (disons 20), puis faire un appel à la base de données à partir de requêtes ultérieures, de sorte que je n'ai pas besoin d'appuyer immédiatement sur la base de données pour tous les enregistrements. Comment y parvenir?

2

Vous devez attendre que votre paginateur soit instancié avant de le "lier" à votre MatTableDataSource, vous écouterez donc généralement les hooks AfterViewInit pour obtenir le paginateur via @ViewChild(MatPaginator) paginator: MatPaginator;

Mais comme vos données sont asynchrones aussi, vous devriez 

1/initialisez une source de données vide 2/remplissez la source de données lorsque vos données sont prêtes 3/liez le paginateur après le rendu de la vue

Pourriez-vous essayer ceci? 

export class YourComponent implements AfterViewInit {

  private this.matdatasource;

  // get refereence to paginator
  @ViewChild(MatPaginator) paginator: MatPaginator;

  constructor (private http: HttpClient) {
    // 1/ init
    this.matdatasource = new MatTableDataSource([]);
    this.http.get('http://example.org?,{headers: this.headers})
      .subscribe(res => { 
        // 2/ populate with data
        this.matdatasource.data = res.data;
      });
  }

  // 3/ link paginator when empty dataSource is created
  // and paginator rendered
  ngAfterViewInit() {
    this.dataSource.paginator = this.paginator;
  }

}
3
Pierre Mallet

D'abord, instancier le paginateur 

@ViewChild(MatPaginator) paginator: MatPaginator;

Puis remplissez le dataSource

this.matdatasource = new MatTableDataSource([])

Et enfin 

this.dataSource.paginator = this.paginator;

Vérifiez ceci pour bien comprendre

0
Akitha_MJ