4

我有一个垫表,每页最多可显示 100 个条目。起初,我在底部有一个垫子分页器,效果很好。现在我被要求在表格顶部设置一个分页器,在表格底部设置另一个分页器,因此如果用户正在寻找位于顶端。
问题是两个分页器必须链接到同一个数据源。我尝试为每个人提供不同的 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;

有人可以指导我吗?

4

4 回答 4

5

我找不到为同一数据源设置 2 个分页器的方法。我这样做的方式是使用数据源的副本设置第二个分页器,然后根据另一个分页器的更改移动每个分页器。

另外,我无法直接设置页面索引或每页项目的属性(表格没有刷新),所以所有的动作都是通过一些逻辑和分页器方法来实现的,比如 previousPage() 或 lastPage()。

唯一的限制是底部的分页器不能更改每页的项目,因为没有一种方法可以让我控制该属性。

你可以在这里看到结果。感谢FabianKüng提供使用 2 个数据源并同步两个分页器的解决方案。

我希望这对某人有用。

于 2019-01-28T18:00:43.003 回答
2

非常感谢Gustavo Alejandro的解决方案。我将它用于我的 Angular v11 项目中。

一个简单的解决方案:

唯一的限制是底部的分页器不能更改每页的项目,因为没有一种方法可以让我控制该属性。

是需要在方法内部使用新值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
    });
  }
}

您不需要导入PageEventfrom @angular/material/paginator,因为您的模板将如下所示:

<mat-paginator #paginatorTop
               (page)="handlePageTop($event)" 
               [length]="resultsLength" 
               [pageSizeOptions]="[10, 25, 50, 100]" 
               [pageSize]="25">
</mat-paginator>
于 2021-01-15T11:26:46.107 回答
0

受@AlleXyS 答案的启发,我创建了完整的工作代码,通过使用相同的数据源在材料表的顶部和底部完成垫分页器。虽然我不得不做出一些重大改变。重要的是将顶部分页器与 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>

类实现:

// ...

@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
    }
于 2021-03-19T03:54:38.567 回答
-1
dataSource = new MatTableDataSource;
@ViewChild('paginatorTop',{static:false}) topPaginator: MatPaginator;
@ViewChild('paginatorBottom',{static:false}) bottomPaginator: MatPaginator;
     
this.dataSource = new MatTableDataSource<any>(this.tableData);

设置api数据到数据源

于 2020-07-29T11:18:18.713 回答