带有分页器的 Mat-table,恢复页面索引后出现 ExpressionChangedAfterItHasBeenChecked 错误

Mat-table with paginator, ExpressionChangedAfterItHasBeenChecked error after restoring page index

我很高兴能为我当前的错误提供一些帮助,因为几天以来我一直在努力寻找解决方案。我想显示一个搜索结果,其中可以包含数百个项目。我使用 mat-tablemat-paginator 以避免单个页面上出现太多项目。代码如下所示:

<mat-paginator #paginator [pageSize]="pageSize" [length]="resultsCount">
</mat-paginator>
<table [dataSource]="itemsDS" mat-table matSort matSortDisableClear>
  <!-- rows / columns defs, nothing too fancy -->
</table>

和 TS :

export class TableComponent implements OnInit {
  public itemsColumns: Array<string> = ["id", "name"];
  public itemsDS: MatTableDataSource<{
    id: number;
    name: string;
  }> = new MatTableDataSource<{ id: number; name: string }>();

  @ViewChild(MatPaginator, { static: false }) set paginator(
    paginator: MatPaginator
  ) {
    this.itemsDS.paginator = paginator;
  }

  @ViewChild(MatSort, { static: false }) set sort(sort: MatSort) {
    this.itemsDS.sort = sort;
  }

  constructor(private router: Router, private itemsService: ItemsService) {}

  ngOnInit() {
    console.log("Initializing items data");
    this.itemsDS.data = this.itemsService.items;
  }

  ngAfterViewInit() {
    if (this.itemsDS.paginator && this.itemsService.currentIndex > -1) {
      console.log("Restoring page index " + this.itemsService.currentIndex);
      this.itemsDS.paginator.pageIndex = this.itemsService.currentIndex;
    }
  }

  ngOnDestroy() {
    const currentPage = this.itemsDS.paginator.pageIndex;
    console.log("Saving page index on destroy " + currentPage);
    this.itemsService.currentIndex = currentPage;
  }

  // a few other functions like getters
}

这会在用户导航到其中一个元素时保存 onDestroy 当前页面,并在用户返回搜索结果时恢复上次查看的页面。

这工作正常,但仅当保存的页面索引的值为 0 时。每当用户从页面索引 > 1 导航到项目时,Angular 会引发 ExpressionChangedAfterItHasBeenChecked 错误。我的代码没有对可以在组件树中更高层的任何地方使用的值进行任何更改。所以我想这是 mat-tablemat-paginator.

之间的交互问题

我创建了一个 very simple stackblitz project 重现此行为,希望有人能找到解决此错误的方法。请注意,当您单击 item11item22(第一页)时,您可以返回列表而不会引发错误。每当您单击 item33(第二页)、item55item66(第三页)时,控制台会在导航回列表时显示错误。

使用最新的 angular 8 个库(核心 8.2.14 和 material 8.2.3)编译。

如有任何帮助,我们将不胜感激。

为了完整起见,我在这里添加我在 this Material repo issue 上得到的答案:

诀窍是在 setTimeout 调用中恢复页面索引:

  ngAfterViewInit() {
    if (this.itemsDS.paginator && this.itemsService.currentIndex > -1) {
      setTimeout(() => {
        this.itemsDS.paginator.pageIndex = this.itemsService.currentIndex;
        this.itemsDS.paginator.page.emit({
          length: this.itemsDS.paginator.getNumberOfPages(),
          pageIndex: this.itemsService.currentIndex,
          pageSize: this.itemsDS.paginator.pageSize
        });
      });
    }
  }

希望这会在 Angular Material 一天内得到纠正。看看 this issue(已经好几年了)。