2

我正在尝试实现一个带有分页的 Angular 材料表,它连接到后端,从 Azure 表存储中检索数据。

我知道,表存储支持ExecuteQuerySegmentedAsync,它返回TableContinuationToken。看起来不错。所以在前端,我得到这样的东西:

interface IPagedResult<T> {
    items: T[];
    isFinalPage: boolean;
    continuationToken: string;
}

interface ILog {
    enqueuedDate: string;
    ...
}

在 component.ts 中的某处:


private logsTableSource: MatTableDataSource<ILog>;
@ViewChild(MatPaginator)paginator: MatPaginator;

ngAfterViewInit() {
   myService.GetRecords(this.paginator.pageSize)
            .subscribe(
               (res: IPagedResult<ILog>) => {
                    this.logsTableSource = new MatTableDataSource<ILog>(res.items);
               });
}

现在我想知道,如何获得页数?并让服务器知道我想要什么特定页面?

continuationToken看起来像这样: 在此处输入图像描述

事实上,我可以用这个 continuationToken 做什么?

为了更好地理解,表格如下所示: 在此处输入图像描述

4

2 回答 2

2

正如@rickvdbosch 所说,TableContinuationToken预计只会向前发展。在分页器中进行一些更改后,我只能向前和向后移动。看起来不错,对我有用: 在此处输入图像描述

如果有人感兴趣。以下是更改:

  1. 实现您自己的MatPaginatorIntl以删除页面标签。我的样子是这样的:
@Injectable()
export class LogsPaginator extends MatPaginatorIntl {
    public getRangeLabel = function (page: number, pageSize: number, length: number) {
        return '';
    };
}
  1. 缓存项目,您之前已加载,因为我们只能使用TableContinuationToken向前移动。您的 component.ts 应如下所示:
export class LogsComponent {
  // As table storage does not support paging per index, we should cache already loaded logs and use continuation token if needed.

  private cachedLogs: ILog[] = [];
  private cachedIndexes: number[] = [];
  private continuationToken = '';

  ngOnInit() {
    this.paginator.page.subscribe(this.pageChanged.bind(this));
  }

  async ngAfterViewInit() {
    await this.loadLogs();
  }

  private async pageChanged(event: PageEvent) {
    if (event.previousPageIndex < event.pageIndex && this.cachedIndexes.indexOf(event.pageIndex) === -1) {
      await this.loadLogs();
    } else {
      this.redrawTable();
    }
  }

  private redrawTable() {
    const start = this.paginator.pageIndex * this.paginator.pageSize;
    const end = start + this.paginator.pageSize;
    this.logsTableSource.data = this.cachedLogs.slice(start, end);
  }


  private async loadLogs() {
      const res = await this.myService.GetLogs(this.paginator.pageSize, this.continuationToken).toPromise();
      this.cachedIndexes.push(this.paginator.pageIndex);
      this.cachedLogs.push(...res.items);
      this.paginator.length = res.isFinalPage ? this.cachedLogs.length : this.cachedLogs.length + 1;
      this.continuationToken = res.continuationToken;

      this.redrawTable();
  }
}
于 2021-01-19T13:57:41.947 回答
2

您链接到的TableContinuationToken文档还指出:

可以通过 TableResultSegment 对象返回部分结果集的方法也返回一个继续标记,该标记可用于后续调用以返回下一组可用结果。

这意味着令牌可用于获取下一组可用结果,您不能将它们用作分页索引。无法为结果的第 7 页制作 TableContinuationToken。

于 2021-01-19T11:05:25.640 回答