components icon indicating copy to clipboard operation
components copied to clipboard

feat(MatTable & MatSort): Ability to track sorting events inside wrapper table component

Open ilyakonrad opened this issue 10 months ago • 0 comments

Feature Description

Allow listening to sort events in the table-wrapping components.

Use Case

I have a custom TableComponent wrapping <mat-table> functionality.

Here's a little sample from table.component.html:

<div #tableWrapper (scroll)="onScroll()">
  <mat-table [dataSource]="data!" class="table">
    <mat-header-row *matHeaderRowDef="columns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: columns"></mat-row>
    <ng-content></ng-content>
  </mat-table>
</div>

As of now, hosts components add matSort directive and listen to (matSortChange) event:

<app-table
    [data]="individualPaymentsTable.data$ | async"
    ...
    matSort
    (matSortChange)="onSort($event)"
  >
    <ng-container [matColumnDef]="Columns.Member">
      <mat-header-cell *matHeaderCellDef mat-sort-header>Header</mat-header-cell>
      <mat-cell *matCellDef="let row">Content</mat-cell>
    </ng-container>
    ...
</app-table>

which creates duplication of a code like this:

onSort(sorting: Sort): void {
  this.individualPaymentsTable.sorting$.next(sorting.direction ? sorting : null)
}

because all our host components handle sorting the same way - they trigger a Subject which triggers an API call.

I want to move some of the logic into the TableComponent to simplify the usage. So I want to pass an object full of subjects (searching$, sorting$, paging$, etc.) to the TableComponent and make it react to sort events on its own like so:

<div class="table-wrapper" #tableWrapper (scroll)="onScroll()">
  <mat-table [dataSource]="data!" class="table" matSort (matSortChange)="onSort($event)">
    <mat-header-row *matHeaderRowDef="columns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: columns"></mat-row>
    <ng-content></ng-content>
  </mat-table>
</div>

However, if I don't add matSort to the host component, I'll get MatSortHeader must be placed within a parent element with the MatSort directive error. And if I do, it'll seem to ignore the matSort set in the TableComponent.

Here's a working example on Stackblitz. Try to sort and notice that TableComponent doesn't get notified about it.

ilyakonrad avatar Apr 18 '24 12:04 ilyakonrad