简体   繁体   中英

Angular 12 table header sort is undefined

I'm working on an upgrade from Angular 8 to 12 and got some errors. Most of them are fixed. The only one left is this one The error

This error means that the sortChange is undefined. The data is displayed in the table. I use this code for the sort function:

ngOnInit(): void {       
this.currentPageIndex = 0;
this.currentPageSize = this.paginationSettings.defaultPageSize;

this.setDataSource(this.entities);

this.sort.sortChange.subscribe((sort: Sort) => {
  debugger;
  return this.sortChanged(sort);
});
}

When the view is loaded I set the event this.sort

  ngAfterViewInit() {
    this.dataSource.paginator = this.paginator;
    this.dataSource.sort = this.sort;
  }

The value if variables are

  @ViewChild(MatTable, { static: true }) table: MatTable<any>;
  @ViewChild(MatPaginator) paginator: MatPaginator;
  @ContentChild(MatSort, { static: true }) sort: MatSort;
  @ContentChildren(MatHeaderRowDef) headerRowDefs!: QueryList<MatHeaderRowDef>;
  @ContentChildren(MatRowDef) rowDefs!: QueryList<MatRowDef<TEntity>>
  @ContentChildren(MatColumnDef, { descendants: true }) columnDefs!: QueryList<MatColumnDef>;
  @Input() entities: TEntity[]; (the data source)

The HTML:

<!-- user component -->
<lq-list
    matSort
    (settingsChanged)="listSettingsChanged.emit($event)"
    [entities]="users"
    [isLoading]="isLoading"
    [displayedColumns]="displayedColumns"
    [paginationSettings]="paginationSettings"
    [totalEntityCount]="totalUserCount"
    >
    <ng-container matColumnDef="email">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Email </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.email}} </mat-cell>
      </ng-container>

    <ng-container matColumnDef="firstName">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Voornaam </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.firstName}} </mat-cell>
    </ng-container>

    <ng-container matColumnDef="lastName">
        <mat-header-cell *matHeaderCellDef mat-sort-header> Achternaam </mat-header-cell>
        <mat-cell *matCellDef="let element"> {{element.lastName}} </mat-cell>
    </ng-container>
    <mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
    <mat-row *matRowDef="let row; columns: displayedColumns;" [routerLink]="['/users/', row.id]" class="pointer"></mat-row>
</lq-list>

<!-- the container-->
<mat-table [dataSource]="dataSource">
  <ng-content></ng-content>
</mat-table>
<lq-paginator
    (page)="paginationSettingsChanged($event)"
    [totalEntityCount]="totalEntityCount"
    [paginationSettings]="paginationSettings"
></lq-paginator>

The ts table component

import { Component, Input, EventEmitter, Output, ViewChild, OnInit, AfterViewInit, SimpleChanges, OnChanges } from '@angular/core';
import { User } from '@app/users/models/user';
import { PaginationSettings } from '@app/core/constants/list-pagination-settings';
import { ListSettingsChangedEvent } from '@app/core/models/list-settings-changed-event';

@Component({
  selector: 'lq-user-list',
  templateUrl: './user-list.component.html',
  styleUrls: ['./user-list.component.scss'],
})
export class UsersListComponent {
  /**
   * The user entities to display
   * @type {User[]}
   * @memberof UsersListComponent
   */
  @Input() users: User[];

  /**
   * Indicator whether the list is loading
   * @type {boolean}
   * @memberof UsersListComponent
   */
  @Input() isLoading: boolean;

  /**
   * Pagination settings
   * @type {PaginationSettings}
   * @memberof UsersListComponent
   */
  @Input() paginationSettings: PaginationSettings;

  /**
   * The total user count
   * @type {number}
   * @memberof UsersListComponent
   */
  @Input() totalUserCount: number;

  /**
   * The event emitter for when the list settings have changed
   * @type {EventEmitter<ListSettingsChangedEvent>}
   * @memberof UsersListComponent
   */
  @Output() listSettingsChanged: EventEmitter<ListSettingsChangedEvent> = new EventEmitter<ListSettingsChangedEvent>();

  /**
   * The columns to display
   * @type {string[]}
   * @memberof UsersListComponent
   */
  displayedColumns: string[] = ['email', 'firstName', 'lastName'];
}

@ContentChild(MatSort, { static: true }) sort: MatSort; will be set after the content has been initialized.

So this.sort is undefined in ngOnInit() . Move it to ngAfterContentInit() .

Also matSort directive needs to be a part of the projected content.

<lq-list
    (settingsChanged)="listSettingsChanged.emit($event)"
    [entities]="users"
    [isLoading]="isLoading"
    [displayedColumns]="displayedColumns"
    [paginationSettings]="paginationSettings"
    [totalEntityCount]="totalUserCount"
    >
    <ng-container matSort>
        <ng-container matColumnDef="email">
            <mat-header-cell *matHeaderCellDef mat-sort-header> Email </mat-header-cell>
            <mat-cell *matCellDef="let element"> {{element.email}} </mat-cell>
          </ng-container>
    ...
    </ng-container>
</lq-list>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM