最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Two mat-paginator with single or multiple datasource is not working - Stack Overflow

programmeradmin3浏览0评论

I have a mat-table that might show up to 5/10/15 entries per page. At first, I had one mat-paginator at the bottom that worked fine. Now I'm being asked to set a paginator at the top and another one at the bottom of the table, so the user won't have to scroll all the way down to reach the paginator if they are looking for an entry that is at the top.

I tried to link both paginator to the same data source. But it didn't worked. So, tried to create 2 datasource, but it also has one limitation.

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.

Also, I couldn't set the page index or items per page properties directly (the table was not refreshing), so all the movements are achieved with some logic and paginator methods like previousPage() or lastPage().

Can anyone help me with this? I'm fine with the solution with either single or multiple datasource.

Working code -> 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>

appponent.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();
      }
    }
  }

I have a mat-table that might show up to 5/10/15 entries per page. At first, I had one mat-paginator at the bottom that worked fine. Now I'm being asked to set a paginator at the top and another one at the bottom of the table, so the user won't have to scroll all the way down to reach the paginator if they are looking for an entry that is at the top.

I tried to link both paginator to the same data source. But it didn't worked. So, tried to create 2 datasource, but it also has one limitation.

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.

Also, I couldn't set the page index or items per page properties directly (the table was not refreshing), so all the movements are achieved with some logic and paginator methods like previousPage() or lastPage().

Can anyone help me with this? I'm fine with the solution with either single or multiple datasource.

Working code -> 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.ponent.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();
      }
    }
  }
Share Improve this question edited Apr 3, 2020 at 14:20 UI_Dev asked Apr 3, 2020 at 14:07 UI_DevUI_Dev 3,42718 gold badges53 silver badges93 bronze badges 3
  • Maybe u can upload your code to StackBlitz ?! – Baruch Mashasha Commented Apr 3, 2020 at 14:17
  • Yes, its there in the question itself. stackblitz./edit/multiple-paginators-knhf4q – UI_Dev Commented Apr 3, 2020 at 14:20
  • issue is not with the design bro, its with the bottom pagination items per page size. data source is not updating – UI_Dev Commented Apr 3, 2020 at 15:18
Add a ment  | 

2 Answers 2

Reset to default 8 +500

No need to use two paginators made some changes in your code, please check it.

Here is my stackblitz code :- https://stackblitz./edit/multiple-paginators-svwwfj

Hope this helps!

This solution works if you want to show one paginator at a time

To solve the above problem, I created a directive scroll-to. In this directive i listened for scroll events and pared the window.pageYOffset with element's nativeElement.offsetTop

if (pageYOffset of window < element's offsetTop) im was setting the property showUpperOne true else property showLowerOne true.

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

I used this directive on div which contains two paginators having the same template reference and one mat table

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

I did set the template reference variable for div #mainDiv="scrolledTo" and accessed the properties of directive to show and hide paginators *ngIf="mainDiv.showLowerOne" , *ngIf="mainDiv.showUpperOne" respectively.

This will show or hide the paginators on scroll but there will be problem with giving the paginator functionality to other paginator once one paginator hides. It has to be set to datasource again.

In order to solve this,i added currentPageSize property and did set the default value as 10 currentPageSize=10;. In order to reassign the paginator to datasource, i listened for the page events using (page)="pageEvents($event)" in template of paginator. and in pageEvents function

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

also on scroll

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

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

发布评论

评论列表(0)

  1. 暂无评论