P
P
prolina2020-11-10 19:02:16
Angular
prolina, 2020-11-10 19:02:16

Problem with pagination in Angular material table?

Hello! I use angular material table in my project. I created a shared component for the table, since there will be several tables. In the parent component, through the service, I receive data from the backend, this is an object of the form: {count: number, items: object []}, where count is the total number of records in the database, and items are the data itself. In my case, I get count: 90, and items contains an array of 20 objects, this is done on the backend so as not to receive all the values ​​\u200b\u200bat once. I pass the received values ​​​​through @Input to the child component, and it turns out that the whole table consists of 20 values ​​in pagination - 1 - 20 of 20, although it should be 1 - 20 of 90. I tried to directly set the length, but to no avail (

table:

<table mat-table [dataSource]="tableDataSource" matSort (matSortChange)="sortTable($event)">

    <!-- action column -->
    <ng-container *ngIf="rowActionIcon?.length" [matColumnDef]="rowActionIcon">
      <mat-header-cell *matHeaderCellDef></mat-header-cell>
      <mat-cell *matCellDef="let element" [id]="rowActionIcon" (click)="emitRowAction(element)">
        <button mat-button>
          <mat-icon>remove_shopping_cart</mat-icon>
        </button>
      </mat-cell>
    </ng-container>


    <ng-container *ngFor="let tableColumn of tableColumns" [cdkColumnDef]="tableColumn.dataKey">

      <!-- if sortable column header -->
      <ng-container *ngIf="tableColumn.isSortable; else notSortable">
        <mat-header-cell *cdkHeaderCellDef [mat-sort-header]="tableColumn.name"
            [arrowPosition]="tableColumn.position === 'right' ? 'before' : 'after'">
          {{tableColumn.name}}
        </mat-header-cell>

      </ng-container>
      <!-- else not sortable -->
      <ng-template #notSortable>
        <mat-header-cell *matHeaderCellDef [class.text-right]="tableColumn.position == 'right'">
          {{tableColumn.name}}
        </mat-header-cell>
      </ng-template>

      <!-- column data -->
      <mat-cell *cdkCellDef="let element" [class.text-right]="tableColumn.position == 'right'">
        {{tableColumn.cell(element)}}
        <!--					{{element | dataPropertyGetter: tableColumn.dataKey}}-->
      </mat-cell>

    </ng-container>
          <mat-header-row *matHeaderRowDef="displayedColumns;"></mat-header-row>
          <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
  </table>

  <!-- Pagination -->
  <mat-paginator 
    *ngIf="isPageable"
    [pageIndex]="0"
    [pageSizeOptions]="paginationSizes"
    [pageSize]="defaultPageSize"
    showFirstLastButtons
    [length]="tableLength"
  >
  </mat-paginator>


public tableDataSource = new MatTableDataSource([]);
  public displayedColumns: string[];
  @Input() length: number;
  @ViewChild(MatPaginator, {static: false}) matPaginator: MatPaginator;
  @ViewChild(MatSort, {static: false}) matSort: MatSort;

  @Input() isPageable = false;
  @Input() isSortable = false;
  @Input() isFilterable = false;
  @Input() tableColumns: TableColumn[];
  @Input() rowActionIcon: string;
  @Input() paginationSizes: number[];
  @Input() defaultPageSize;
  @Input() tableLength: number;

  @Output() sort: EventEmitter<Sort> = new EventEmitter();
  @Output() rowAction: EventEmitter<any> = new EventEmitter<any>();

  // this property needs to have a setter, to dynamically get changes from parent component
  @Input() set tableData(data: KeywordCollectionModel) {
    this.setTableDataSource(data);
  }

  constructor() {}

  ngOnChanges(changes: SimpleChanges): void {
    if(changes.tableColumns.currentValue) {
      const columnNames = this.tableColumns.map((tableColumn: TableColumn) => tableColumn.dataKey);
      // this.columnsToDisplay = this.displayedColumns.map(c => c.columnDef);
      if (this.rowActionIcon) {
        this.displayedColumns = [this.rowActionIcon, ...columnNames];
      } else {
        this.displayedColumns = columnNames;
      }
    }
  }

  // we need this, in order to make pagination work with *ngIf
  ngAfterViewInit(): void {
    this.tableDataSource.paginator = this.matPaginator;
  }

  setTableDataSource(data: any) {
    this.tableDataSource = new MatTableDataSource<any>(data);
    this.tableDataSource.paginator = this.matPaginator;
    this.tableDataSource.sort = this.matSort;
  }

  applyFilter(event: Event) {
    const filterValue = (event.target as HTMLInputElement).value;
    this.tableDataSource.filter = filterValue.trim().toLowerCase();
  }

  sortTable(sortParameters: Sort) {
    // defining name of data property, to sort by, instead of column name
    sortParameters.active = this.tableColumns.find(column => column.name === sortParameters.active).dataKey;
    this.sort.emit(sortParameters);
  }

  emitRowAction(row: any) {
    this.rowAction.emit(row);
  }
}


parent component:

<fo-table
  [tableData]="data"
  [tableColumns]="displayedColumns"
  [isFilterable]="true"
  [isPageable]="true"
  [paginationSizes]="[20,50,100]"
  [defaultPageSize]="20"
  [tableLength]="tableLength"
  [rowActionIcon]="'remove_shopping_cart'"
  ></fo-table>

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question