【问题标题】:Two mat-paginator with single or multiple datasource is not working具有单个或多个数据源的两个 mat-paginator 不起作用
【发布时间】:2020-07-15 17:31:54
【问题描述】:

我有一个垫表,每页最多可显示 5/10/15 个条目。起初,我在底部有一个垫子分页器,效果很好。现在我被要求在表格顶部设置一个分页器,在表格底部设置另一个分页器,因此如果用户正在寻找位于的条目,则无需一直向下滚动即可到达分页器顶部。

我尝试将两个分页器链接到同一个数据源。但它没有奏效。因此,尝试创建 2 个数据源,但它也有一个限制。

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

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

谁能帮我解决这个问题?我对具有单个或多个数据源的解决方案感到满意。

工作代码 -> STACKBLITZ

<mat-paginator #paginatorTop (page)="pageEvent = handlePageTop($event)" [length]="length" [pageSizeOptions]="[5, 10, 15]" showFirstLastButtons></mat-paginator>

<mat-paginator #paginatorBottom (page)="pageEvent = handlePageBottom($event)" [length]="length" [pageSizeOptions]="[5, 10, 15]" showFirstLastButtons></mat-paginator>

app.component.ts

ngOnInit() {
    this.dataSource2.paginator = this.bottomPaginator;
    this.dataSource.paginator = this.topPaginator;

    this.topPaginator.length = this.dataSource.data.length;
    this.bottomPaginator.length = this.dataSource2.data.length;
  }


  public handlePageTop(e: any) {
    let {pageSize} = e;

    this.bottomPaginator.pageSize = pageSize;

    if(!this.topPaginator.hasNextPage()){
      this.bottomPaginator.lastPage();
    }else if(!this.topPaginator.hasPreviousPage()){
      this.bottomPaginator.firstPage();
    }else{
      if(this.topPaginator.pageIndex < this.bottomPaginator.pageIndex){
        this.bottomPaginator.previousPage();
      } else  if(this.topPaginator.pageIndex >this.bottomPaginator.pageIndex){
        this.bottomPaginator.nextPage();
      }
    }
  }

  public handlePageBottom(e: any) {

    if(!this.bottomPaginator.hasNextPage()){
      this.topPaginator.lastPage();
    }else if(!this.bottomPaginator.hasPreviousPage()){
      this.topPaginator.firstPage();
    }else{
      if(this.bottomPaginator.pageIndex < this.topPaginator.pageIndex){
        this.topPaginator.previousPage();
      } else  if(this.bottomPaginator.pageIndex > this.topPaginator.pageIndex){
        this.topPaginator.nextPage();
      }
    }
  }

【问题讨论】:

  • 也许你可以将你的代码上传到 StackBlitz ?!
  • 是的,问题本身就在那里。 stackblitz.com/edit/multiple-paginators-knhf4q
  • 问题不在于设计兄弟,它与每页大小的底部分页项目有关。数据源未更新

标签: javascript html angular typescript pagination


【解决方案1】:

不需要使用两个分页器对你的代码做了一些改动,请检查一下。

这是我的 stackblitz 代码:- https://stackblitz.com/edit/multiple-paginators-svwwfj

希望这会有所帮助!

【讨论】:

  • 帅哥!但是底部分页器第一次出现问题。如果我们选择 10 页大小,则不会触发
  • 不,我观察到介于两者之间的一些间歇性问题,不确定究竟是哪种情况。我在多次测试时观察到
  • @UI_Dev 您可能已经观察到,当您在最后一页然后更改页面大小时,它不会刷新这是行为。要更改这一点,您需要围绕此添加自定义逻辑。
  • @GouravGarg,是的,当我在最后一页时,当我尝试更改 15 时,它不起作用。
  • 那么你必须编写自定义方法来在更改 pageSize 时重置 pageIndex
【解决方案2】:

如果您想一次显示一个分页器,此解决方案很有效

为了解决上述问题,我创建了一个指令滚动到。在这个指令中,我监听了滚动事件并将window.pageYOffset 与元素的nativeElement.offsetTop 进行比较

if (pageYOffset of window &lt; element's offsetTop)im 正在设置属性showUpperOnetrue else 属性showLowerOnetrue。

import {Directive,HostListener,ElementRef} from '@angular/core'
@Directive(
  {
    selector:"[scrolledTo]",
    exportAs:"scrolledTo"
  }
)
export class ScrollDirective {

  showUpperOne=true;
  showLowerOne=false;
  constructor(private el:ElementRef){}
  @HostListener("window:scroll",['$event'])
  onScroll(){
    const elementPosition = this.el.nativeElement.offsetTop;
    const scrollPosition = window.pageYOffset;
    this.showUpperOne=scrollPosition<elementPosition
    this.showLowerOne = scrollPosition>= elementPosition;
  }
}

我在 div 上使用了这个指令,它包含两个具有相同模板引用和一个 mat 表的分页器

<div #mainDiv="scrolledTo" scrolledTo  class="example-container mat-elevation-z8">
  <mat-paginator *ngIf="mainDiv.showUpperOne" #paginator
                 [pageSize]="currentPageSize"
                 [pageSizeOptions]="[5, 10, 20]"
                 (page)="pageEvents($event)"
                 [showFirstLastButtons]="true">
  </mat-paginator>
  <mat-table #table [dataSource]="dataSource">...
  </mat-table>
  <mat-paginator *ngIf="mainDiv.showLowerOne" #paginator
                 [pageSize]="currentPageSize"
                 [pageSizeOptions]="[5, 10, 20]"
                 (page)="pageEvents($event)"
                 [showFirstLastButtons]="true">
  </mat-paginator>

我确实为 div #mainDiv="scrolledTo" 设置了模板引用变量 并访问指令的属性以显示和隐藏分页符 *ngIf="mainDiv.showLowerOne" ,*ngIf="mainDiv.showUpperOne"

这将在滚动时显示或隐藏分页器,但是一旦隐藏一个分页器,将分页器功能提供给其他分页器就会出现问题。它必须再次设置为数据源。

为了解决这个问题,我添加了 currentPageSize 属性并将默认值设置为 10currentPageSize=10;。为了将分页器重新分配给数据源,我在分页器模板中使用(page)="pageEvents($event)" 监听页面事件。 并在 pageEvents 函数中

pageEvents(event){
    this.currentPageSize=event.pageSize;
  }

也可以滚动

 @HostListener("window:scroll",['$event'])
  onScroll(){
    setTimeout(()=> this.dataSource.paginator = this.paginator,0)  
  }

Stackblitz:https://stackblitz.com/edit/angular-nbtcgz

【讨论】:

  • 欣赏你的工作!但我认为这个解决方案不适用于我的情况,因为它在滚动时会有一些延迟
  • 所以你没有找到解决办法?
  • 这种方法也存在问题。当我们选择顶部分页器的每页下拉菜单时,底部分页器消失
  • 不,我认为我们需要根据用户的视图显示和隐藏上下分页符,而不是显示两个分页符。如果可以,请重申您想要的解决方案...我会尽力解决
  • 当然,我需要的解决方案是让两个垫子分页器一个在顶部,另一个在底部以相互同步。我可以使用这两个分页器来控制表格。我有顶部分页器正常工作的代码。我已经发出了底部Paginator未在选择每页下拉的项目时触发数据表。另外,为了尽快得到正确答案,我已经宣布悬赏500这个问题。
猜你喜欢
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-09
  • 1970-01-01
  • 2019-10-23
  • 1970-01-01
相关资源
最近更新 更多