Angular MatPaginator 和 Azure Table 存储
Angular MatPaginator and Azure Table Storage
我正在尝试实现一个带有分页功能的 Angular material table,它连接到后端,从 Azure Table 存储中检索数据。
我知道,Table 存储支持 ExecuteQuerySegmentedAsync, which returns 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 做什么?
为了更好地理解 table 的样子:
您链接到的 TableContinuationToken
文档还指出:
A method that may return a partial set of results via a TableResultSegment object also returns a continuation token, which can be used in a subsequent call to return the next set of available results.
这意味着令牌可用于获取下一组可用结果,您不能将它们用作分页索引。无法为结果的第 7 页制作 TableContinuationToken。
正如@rickvdbosch 所说,TableContinuationToken
只希望继续前进。在对分页器进行一些更改后,我只能向前和向后移动。看起来不错,适合我:
如果有人感兴趣。以下是更改:
- 实施您自己的
MatPaginatorIntl
以删除页面标签。我的样子是这样的:
@Injectable()
export class LogsPaginator extends MatPaginatorIntl {
public getRangeLabel = function (page: number, pageSize: number, length: number) {
return '';
};
}
- 您之前加载的缓存项目,因为我们可以 ONLY 使用 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();
}
}
我正在尝试实现一个带有分页功能的 Angular material table,它连接到后端,从 Azure Table 存储中检索数据。
我知道,Table 存储支持 ExecuteQuerySegmentedAsync, which returns 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 做什么?
为了更好地理解 table 的样子:
您链接到的 TableContinuationToken
文档还指出:
A method that may return a partial set of results via a TableResultSegment object also returns a continuation token, which can be used in a subsequent call to return the next set of available results.
这意味着令牌可用于获取下一组可用结果,您不能将它们用作分页索引。无法为结果的第 7 页制作 TableContinuationToken。
正如@rickvdbosch 所说,TableContinuationToken
只希望继续前进。在对分页器进行一些更改后,我只能向前和向后移动。看起来不错,适合我:
如果有人感兴趣。以下是更改:
- 实施您自己的
MatPaginatorIntl
以删除页面标签。我的样子是这样的:
@Injectable()
export class LogsPaginator extends MatPaginatorIntl {
public getRangeLabel = function (page: number, pageSize: number, length: number) {
return '';
};
}
- 您之前加载的缓存项目,因为我们可以 ONLY 使用 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();
}
}