2个mat-paginator用于相同的数据源

时间:2019-01-25 23:26:37

标签: angular angular-material paginator mat-table

我有一个席子表,每页最多可以显示100个条目。一开始,我在底部有一个垫式分页器,效果很好。现在,系统要求我在表格的顶部设置一个分页器,在表格的底部设置一个分页器,这样,如果用户要查找的条目位于顶端。
问题是两个分页程序必须链接到相同的数据源。 我尝试为每个ID赋予不同的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 个答案:

答案 0 :(得分:1)

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

此外,我无法直接设置页面索引或每页项目的属性(该表未刷新),因此所有移动都是通过某些逻辑和分页器方法(例如previousPage()或lastPage())实现的。

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

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

我希望这对某人有用。

答案 1 :(得分:1)

非常感谢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
    });
  }
}

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

<mat-paginator #paginatorTop
               (page)="handlePageTop($event)" 
               [length]="resultsLength" 
               [pageSizeOptions]="[10, 25, 50, 100]" 
               [pageSize]="25">
</mat-paginator>

答案 2 :(得分:0)

list.flatten.lift(n)

将api数据设置为数据源

答案 3 :(得分:0)

受到@AlleXyS 回答的启发,我创建了完整的工作代码,以使用相同的数据源在材料表的顶部和底部完成 mat-paginator。虽然我不得不做出一些重大改变。重要的是将顶部分页器与 handlePaginatorBottom 方法连接起来,反之亦然。这样两人就保持同步。当在 handlePaginatorTop 内部使用底部分页器时,会发出一个 page 事件,以触发分页器一的 page observable 以根据数据加载。

这是完整的实现,因为它有点棘手。

模板实现:

<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
    }