I wonder if anyone has ever solved this problem!
I am currently developing an AdministrationComponent (which is something like a singleton for CRUD operations), which is meant to manage the data on 4 different tables by sending the operations via HTTP request (encapsulated in a service) to the back-end, which then the results are sent to the client via WebSockets (preparing for a future where multiple clients are on this component simultaneously).
I am retrieving the data with HTTP requests to the backend, which I have no problem showing it in each of the tables.
I am instantiating Material Dialogs which encapsulate each of the CRUD operation for each of the tables. These, when validated and completed, send the correspondent HTTPRequest to the backend with the operation and its data. (Each table has its own service)
Then, I have a separate service that implements WebSockets and this is the one who updates the data displayed on the tables (because this AdministrationComponent will be used by more than one client).
I have to have to do validation(maybe not called validation(?)) that depends on data present in more than one table. For instance: let's say we have table A, B and C. One item from A can be related to items from C, but It can only be accessible if both A and B have a property in common. Since this type of operations is present in more than one table, I am planning on keeping this kind-of-a singleton component architecture, but please prove me wrong.
now, the problem: since showing the data on the tables is working just fine, my problem is with the sorting, filtering and the pagination of each table.
There seems to be no error on the code, but it simply only works for the first table and not for the other ones, as I cannot figure out how to reference the matSort and matPaginator correctly. Initialy, I was doing the ViewChild for the matSort and matPaginator like:
@Component({
selector: 'app-administration',
templateUrl: './administration.component.html',
styleUrls: ['./administration.component.scss']
})
export class AdministrationComponent implements OnInit {
users: any = [];
userTable_displayedColumns: string[] = ['name', 'organization', 'updatedAt', 'userActionsColumn'];
userTable_dataSource: MatTableDataSource<any>;
@ViewChild(MatPaginator, { static: true }) userTable_paginator: MatPaginator;
@ViewChild(MatSort, { static: true }) userTable_sort: MatSort;
userTable_applyFilter(filterValue: string): void {
this.userTable_dataSource.filter = filterValue.trim().toLowerCase();
if (this.userTable_dataSource.paginator) {
this.userTable_dataSource.paginator.firstPage();
}
}
constructor (/* service Injection here */) {
this.userTable_dataSource = new MatTableDataSource;
// initialization of table with Promised HTTP request
// initialization of websockets channel which updates the data according to the backend
// this is done for the 4 different tables
}
ngOnInit(): void {
this.userTable_dataSource.paginator = this.userTable_paginator;
this.userTable_dataSource.sort = this.userTable_sort;
// this is done for the 4 different tables
}
// and the rest of the code here is filtering on the different tables,
//as well as launching Material Dialogs which are working fine
}
and the template (each table is in its own tab-pane):
<!-- Users -->
<div class="tab-pane active" id="link1">
<div class="row">
<div class="col-md">
<button class="btn btn-enging btn-fill btn-wd mat-raised-button" mat-raised-button="" type="submit"
(click)="openDialogCreateUser()">
<span class="mat-button-wrapper">
<i class="material-icons">person_add</i> Adicionar Utilizador
</span>
<div class="mat-button-ripple mat-ripple" matripple=""></div>
<div class="mat-button-focus-overlay"></div>
</button>
</div>
<div class="col-md-6">
<mat-form-field class="example-full-width">
<input matInput placeholder="Encontrar..." (keyup)="userTable_applyFilter($event.target.value)"
value="">
</mat-form-field>
</div>
</div>
<div class="mat-elevation-z8">
<table mat-table [dataSource]="userTable_dataSource" matSort>
<tr mat-header-row *matHeaderRowDef="userTable_displayedColumns"></tr>
<ng-container matColumnDef="userType">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Tipo de User </th>
<td mat-cell *matCellDef="let row"> {{row.userType}} </td>
</ng-container>
<ng-container matColumnDef="username">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Username </th>
<td mat-cell *matCellDef="let row"> {{row.username}} </td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Nome </th>
<td mat-cell *matCellDef="let row"> {{row.name}} </td>
</ng-container>
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
<td mat-cell *matCellDef="let row"> {{row.email}} </td>
</ng-container>
<ng-container matColumnDef="organization">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Organização </th>
<td mat-cell *matCellDef="let row"> {{getOrganizationNameByID(row.organization)}} </td>
</ng-container>
<ng-container matColumnDef="updatedAt">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Último login </th>
<td mat-cell *matCellDef="let row"> {{row.updatedAt | date:'HH:mm, dd/MM/y' }} </td>
</ng-container>
<ng-container matColumnDef="userActionsColumn">
<th mat-header-cell *matHeaderCellDef mat-sort-header style="white-space: nowrap;"> Acções </th>
<td mat-cell *matCellDef="let row">
<div class="row">
<span class="mat-button-wrapper" (click)="openDialogViewUser(row)" style="cursor: pointer">
<i class="material-icons" style="color:#163b65">remove_red_eye</i>
</span>
<span class="mat-button-wrapper" (click)="openDialogEditUser(row)" style="cursor: pointer">
<i class="material-icons" style="color:rgba(22, 59, 101, 1)">edit</i>
</span>
<span class="mat-button-wrapper" (click)="openDialogRemoveUser(row)" style="cursor: pointer">
<i class="material-icons" style="color:rgba(22, 59, 101, 1)">clear</i>
</span>
</div>
</td>
</ng-container>
<tr mat-row *matRowDef="let row; columns: userTable_displayedColumns;"></tr>
</table>
<mat-paginator [pageSizeOptions]="[10, 25, 100]"></mat-paginator>
</div>
</div>
<!-- Organizations, and so on ... -->
But then, I figured out how to use ViewChild properly(I guess) and tried: (referencing: https://stackoverflow.com/a/49015542/8919846 )
@ViewChild('userTablePaginator', { static: true }) userTable_paginator: MatPaginator;
@ViewChild('userTableSort', { static: true }) userTable_sort: MatSort;
template:
<table mat-table [dataSource]="userTable_dataSource" #userTableSort="matSort" matSort>
<mat-paginator #userTablePaginator="matSort" [pageSizeOptions]="[10, 25, 100]"></mat-paginator>
but it does not work.
Anyone have a clue how I can make it work? :)