Les personnes souhaitant faire de la pagination et du tri côté client sont priées de se reporter à ce lien
Voici ce que j'ai essayé. Les données sont en cours de chargement dans la console. mais il n'est pas affiché sur la grille ou le tableau.
Je n'ai aucune erreur dans la console. Je suis capable de voir les données dans la console mais les données ne sont pas chargées dans la grille.
Quelqu'un peut-il me dire ce que je fais mal?
La base de données réelle à partir de laquelle les données sont émises.
export class FormsDatabase {
formsList = new BehaviorSubject([]);
get data(){
return this.formsList.value;
}
constructor(private _formsServicedata: FormsService){
this._formsServicedata.getAllFormData('').subscribe((form)=>{
console.log("Form DataSource: ");
this.formsList.next(form);
})
}
}
export class FormDataSource extends DataSource<any>{
constructor( private formsDb: FormsDatabase,public
paginator:MatPaginator , public sort: MatSort
) {
super()
}
connect():Observable<any>{
const formsData=[
this.formsDb.formsList ,
this.sort.sortChange
];
return Observable.merge(...formsData).map(()=>{
this.getSortedData();
})
}
Fonction de tri pour trier les données
getSortedData(){
const data = this.formsDb.data.slice();
if(!this.sort.active || this.sort.direction==''){ return data;}
return data.sort((a,b)=>{
let propertyA:number|string='';
let propertyB:number|string='';
switch(this.sort.active)
{
case 'formname': [propertyA,propertyB]=
[a.formname,b.formname];break;
case 'displaytext': [propertyA,propertyB]=
[a.displaytext,b.displaytext];break;
case 'sortorder': [propertyA,propertyB]=
[a.sortorder,b.sortorder];break;
}
let valueA = isNaN(+propertyA) ? propertyA : +propertyA;
let valueB = isNaN(+propertyB) ? propertyB : +propertyB;
return (valueA < valueB?-1:1)*(this.sort.direction=='asc'?1:-1);
});
}
disconnect() { }
}
HTML
<mat-table #table [dataSource]="dataSource" matSort>
<ng-container matColumnDef="formname">
<mat-header-cell *matHeaderCellDef mat-sort-header> FORM NAME
</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.formname}}
</mat-cell>
</ng-container>
<ng-container matColumnDef="displaytext">
<mat-header-cell *matHeaderCellDef mat-sort-header> DISPLAY TEXT </mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.displaytext}} </mat-cell>
</ng-container>
<ng-container matColumnDef="sortorder">
<mat-header-cell *matHeaderCellDef mat-sort-header> SORT ORDER</mat-header-cell>
<mat-cell *matCellDef="let element"> {{element.sortorder}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
<mat-paginator #paginator
[pageSize]="10"
[pageSizeOptions]="[5, 10, 20]"
[showFirstLastButtons]="true">
</mat-paginator>
</div>
Un service:
Forms Service utilise la méthode ci-dessous qui renvoie la liste des formulaires comme observable.
getAllFormData(orderBy:string) {
return this.af.list('/forms');
}
Je reproduis votre code et, tout comme vous, je ne peux pas le faire fonctionner comme les exemples fournis par l'équipe de matériaux angulaires, mais j'ai utilisé une solution de contournement pour que la fonction de tri fonctionne.
export class FormDataSource extends DataSource<any> {
constructor(private formsDb: FormsDatabase, public paginator: MatPaginator,
public sort: MatSort) {
super();
this.sort.sortChange.subscribe(t =>
this.formsDb.formsList.next(this.getSortedData()));
}
connect(): Observable<any[]> {
return this.formsDb.formsList;
}
getSortedData () {
const data = this.formsDb.data.slice();
if (!this.sort.active || this.sort.direction === '') {
return data;
}
return data.sort((a, b) => {
let propertyA: number | string = '';
let propertyB: number | string = '';
switch (this.sort.active) {
case 'formname':
[propertyA, propertyB] =
[a.formname, b.formname];
break;
case 'displaytext':
[propertyA, propertyB] =
[a.displaytext, b.displaytext];
break;
case 'sortorder':
[propertyA, propertyB] =
[a.sortorder, b.sortorder];
break;
}
const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
const valueB = isNaN(+propertyB) ? propertyB : +propertyB;
return (valueA < valueB ? -1 : 1) * (this.sort.direction == 'asc' ? 1 : -1);
});
}
disconnect() {
}
}
Après la vue init
Après avoir appliqué le filtre
Ajoutez un ngIf="dataSource"
dans la balise <mat-table>
.
Ce problème se produit si les données sont asynchrones. le DOM est chargé avant que les données ne soient extraites.
Vérifiez la dataSource
avant de rendre le DOM.
Dans l'exemple https://material.angular.io/components/table/overview , Vous devez en supprimer l'élément tr
. Mauvaise implémentation:
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
Mise en œuvre correcte:
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
Ce problème se produit en raison de la façon dont angular détecte les modifications, ce qui parfois ne se produit pas et aucun re-rendu n'est déclenché.
Pour résoudre ce problème, importez ChangeDetectorRef
à partir de '@angular/core'
, insérez-le dans le composant constructor (cd: ChangeDetectorRef)
, puis utilisez-le après le tri des données:
return Observable.merge(...formsData).map(()=>{
this.getSortedData();
this.cd.detectChanges(); // or this.cd.markForCheck() if detectChanges does not work.
})