2 相同数据源的 mat-paginator
2 mat-paginator for the same data source
我有一个 mat-table,每页最多可显示 100 个条目。起初,我在底部有一个 mat-paginator,效果很好。现在我被要求在 table 的顶部设置一个分页器,在 table 的底部设置另一个分页器,这样如果用户正在寻找一个位于顶部的条目。
问题是两个分页器必须链接到相同的数据源。
我尝试为每个人提供不同的 id,使用 ViewChild 获取它们并将它们分配给相同的数据源,但它只适用于其中一个。
main.component.ts:
flights: Flight[] =[];
dataSource = new MatTableDataSource<Flight>(this.flights);
@ViewChild('PAGINATOR') paginator: MatPaginator;
@ViewChild('OTROPAGINATOR') paginatorOtro: MatPaginator;
main.component.html:
<mat-paginator #PAGINATOR (page)="pageEvent = handlePage($event)"
[length]="length" [pageSizeOptions]="[25, 50, 100]" showFirstLastButtons>
</mat-paginator>
<table mat-table ...> ... </table>
<mat-paginator #OTROPAGINATOR (page)="pageEvent = handlePage($event)"
[length]="length" [pageSizeOptions]="[25, 50, 100]" showFirstLastButtons>
</mat-paginator>
将分页器链接到数据源:
this.dataSource = new MatTableDataSource<Flight>(this.flights);
this.dataSource.paginator = this.paginator;
this.dataSource.paginator = this.paginatorOtro;
有人可以指导我吗?
我找不到为同一数据源设置 2 个分页器的方法。我这样做的方法是使用数据源的副本设置第二个分页器,然后根据另一个分页器的更改移动每个分页器。
此外,我无法直接设置页面索引或每页项目属性(table 不刷新),因此所有移动都是通过一些逻辑和分页器方法实现的,如 previousPage() 或lastPage().
唯一的限制是底部的分页器无法更改每页的项目,因为没有一种方法可以让我控制 属性。
您可以看到关于使用 2 个数据源并同步两个分页器的解决方案的结果 here. Thanks FabianKüng。
我希望这对某人有用。
dataSource = new MatTableDataSource;
@ViewChild('paginatorTop',{static:false}) topPaginator: MatPaginator;
@ViewChild('paginatorBottom',{static:false}) bottomPaginator: MatPaginator;
this.dataSource = new MatTableDataSource<any>(this.tableData);
设置api数据到数据源
非常感谢 Gustavo Alejandro 提供的解决方案。我将它用于我的 angular v11 项目。
一个简单的解决方案:
The only limitation is that the paginator at the bottom can't change
items per page, since there isn't a method that lets me control that
property.
是在 handlePageBottom()
方法内部需要使用新值为 topPaginator
发出事件:
handlePageTop(e): void {
const {pageSize, pageIndex} = e;
this.bottomPaginator.pageSize = pageSize;
this.bottomPaginator.pageIndex = pageIndex;
}
handlePageBottom(e): void {
const {pageSize, pageIndex} = e;
this.topPaginator.pageSize = pageSize;
this.topPaginator.pageIndex = pageIndex;
this.topPaginator.page.emit(e);
}
ngAfterViewInit(): void {
merge(
this.topPaginator.page // we don't need both
).pipe(startWith({}),
debounceTime(300)).subscribe() => {
// do something
});
}
}
您不需要从 @angular/material/paginator
导入 PageEvent
,因为您的模板将如下所示:
<mat-paginator #paginatorTop
(page)="handlePageTop($event)"
[length]="resultsLength"
[pageSizeOptions]="[10, 25, 50, 100]"
[pageSize]="25">
</mat-paginator>
受@AlleXyS 回答的启发,我创建了完整的工作代码,通过使用相同的数据源在 material table 的顶部和底部完成垫分页器。尽管我不得不做出一些重大改变。重要的是将顶部分页器与 handlePaginatorBottom 方法连接起来,反之亦然。这样两者就保持同步。当在 handlePaginatorTop 中使用底部分页器时,将发出一个页面事件以触发分页器一的页面可观察到根据数据加载。
这里是完整的实现,因为它有点棘手。
模板实现:
<mat-paginator
#paginatorTop
(page)="handlePaginatorBottom($event)"
[length]="resultsLength"
[pageSize]="30"
></mat-paginator>
<div class="table-container">
<table
mat-table
[dataSource]="data"
multiTemplateDataRows
>
// ...
</table>
</div>
<mat-paginator
#paginatorBottom
(page)="handlePaginatorTop($event)"
[length]="resultsLength"
[pageSize]="30"
></mat-paginator>
Class 实施:
// ...
@ViewChild('paginatorTop', { static: false })
paginatorTop: MatPaginator
@ViewChild('paginatorBottom', { static: false })
paginatorBottom: MatPaginator
// ...
ngAfterViewInit() {
this.paginatorTop.page
.pipe(
startWith({}),
switchMap(() => {
// ...
// use switch map to load data via another observable
})
map((data) => {
this.isLoadingResults = false
this.resultsLength = data.count
return data.items
}),
catchError(() => {
this.isLoadingResults = false
return of([])
})
)
.subscribe((data) => {
this.data = data
})
}
handlePaginatorTop(e): void {
const { pageSize, pageIndex } = e
this.paginatorTop.pageSize = pageSize
this.paginatorTop.pageIndex = pageIndex
this.paginatorTop.page.emit(e)
}
handlePaginatorBottom(e): void {
const { pageSize, pageIndex } = e
this.paginatorBottom.pageSize = pageSize
this.paginatorBottom.pageIndex = pageIndex
}
我有一个 mat-table,每页最多可显示 100 个条目。起初,我在底部有一个 mat-paginator,效果很好。现在我被要求在 table 的顶部设置一个分页器,在 table 的底部设置另一个分页器,这样如果用户正在寻找一个位于顶部的条目。
问题是两个分页器必须链接到相同的数据源。
我尝试为每个人提供不同的 id,使用 ViewChild 获取它们并将它们分配给相同的数据源,但它只适用于其中一个。
main.component.ts:
flights: Flight[] =[];
dataSource = new MatTableDataSource<Flight>(this.flights);
@ViewChild('PAGINATOR') paginator: MatPaginator;
@ViewChild('OTROPAGINATOR') paginatorOtro: MatPaginator;
main.component.html:
<mat-paginator #PAGINATOR (page)="pageEvent = handlePage($event)"
[length]="length" [pageSizeOptions]="[25, 50, 100]" showFirstLastButtons>
</mat-paginator>
<table mat-table ...> ... </table>
<mat-paginator #OTROPAGINATOR (page)="pageEvent = handlePage($event)"
[length]="length" [pageSizeOptions]="[25, 50, 100]" showFirstLastButtons>
</mat-paginator>
将分页器链接到数据源:
this.dataSource = new MatTableDataSource<Flight>(this.flights);
this.dataSource.paginator = this.paginator;
this.dataSource.paginator = this.paginatorOtro;
有人可以指导我吗?
我找不到为同一数据源设置 2 个分页器的方法。我这样做的方法是使用数据源的副本设置第二个分页器,然后根据另一个分页器的更改移动每个分页器。
此外,我无法直接设置页面索引或每页项目属性(table 不刷新),因此所有移动都是通过一些逻辑和分页器方法实现的,如 previousPage() 或lastPage().
唯一的限制是底部的分页器无法更改每页的项目,因为没有一种方法可以让我控制 属性。
您可以看到关于使用 2 个数据源并同步两个分页器的解决方案的结果 here. Thanks FabianKüng。
我希望这对某人有用。
dataSource = new MatTableDataSource;
@ViewChild('paginatorTop',{static:false}) topPaginator: MatPaginator;
@ViewChild('paginatorBottom',{static:false}) bottomPaginator: MatPaginator;
this.dataSource = new MatTableDataSource<any>(this.tableData);
设置api数据到数据源
非常感谢 Gustavo Alejandro 提供的解决方案。我将它用于我的 angular v11 项目。
一个简单的解决方案:
The only limitation is that the paginator at the bottom can't change items per page, since there isn't a method that lets me control that property.
是在 handlePageBottom()
方法内部需要使用新值为 topPaginator
发出事件:
handlePageTop(e): void {
const {pageSize, pageIndex} = e;
this.bottomPaginator.pageSize = pageSize;
this.bottomPaginator.pageIndex = pageIndex;
}
handlePageBottom(e): void {
const {pageSize, pageIndex} = e;
this.topPaginator.pageSize = pageSize;
this.topPaginator.pageIndex = pageIndex;
this.topPaginator.page.emit(e);
}
ngAfterViewInit(): void {
merge(
this.topPaginator.page // we don't need both
).pipe(startWith({}),
debounceTime(300)).subscribe() => {
// do something
});
}
}
您不需要从 @angular/material/paginator
导入 PageEvent
,因为您的模板将如下所示:
<mat-paginator #paginatorTop
(page)="handlePageTop($event)"
[length]="resultsLength"
[pageSizeOptions]="[10, 25, 50, 100]"
[pageSize]="25">
</mat-paginator>
受@AlleXyS 回答的启发,我创建了完整的工作代码,通过使用相同的数据源在 material table 的顶部和底部完成垫分页器。尽管我不得不做出一些重大改变。重要的是将顶部分页器与 handlePaginatorBottom 方法连接起来,反之亦然。这样两者就保持同步。当在 handlePaginatorTop 中使用底部分页器时,将发出一个页面事件以触发分页器一的页面可观察到根据数据加载。
这里是完整的实现,因为它有点棘手。
模板实现:
<mat-paginator
#paginatorTop
(page)="handlePaginatorBottom($event)"
[length]="resultsLength"
[pageSize]="30"
></mat-paginator>
<div class="table-container">
<table
mat-table
[dataSource]="data"
multiTemplateDataRows
>
// ...
</table>
</div>
<mat-paginator
#paginatorBottom
(page)="handlePaginatorTop($event)"
[length]="resultsLength"
[pageSize]="30"
></mat-paginator>
Class 实施:
// ...
@ViewChild('paginatorTop', { static: false })
paginatorTop: MatPaginator
@ViewChild('paginatorBottom', { static: false })
paginatorBottom: MatPaginator
// ...
ngAfterViewInit() {
this.paginatorTop.page
.pipe(
startWith({}),
switchMap(() => {
// ...
// use switch map to load data via another observable
})
map((data) => {
this.isLoadingResults = false
this.resultsLength = data.count
return data.items
}),
catchError(() => {
this.isLoadingResults = false
return of([])
})
)
.subscribe((data) => {
this.data = data
})
}
handlePaginatorTop(e): void {
const { pageSize, pageIndex } = e
this.paginatorTop.pageSize = pageSize
this.paginatorTop.pageIndex = pageIndex
this.paginatorTop.page.emit(e)
}
handlePaginatorBottom(e): void {
const { pageSize, pageIndex } = e
this.paginatorBottom.pageSize = pageSize
this.paginatorBottom.pageIndex = pageIndex
}