Два мата-пагинатора с одним или несколькими источниками данных не работают - PullRequest
1 голос
/ 03 апреля 2020

У меня есть таблица соответствия, которая может отображать до 5/10/15 записей на страницу. Сначала у меня был один коврик в нижней части, который работал нормально. Теперь меня просят установить paginator вверху и еще один внизу таблицы, чтобы пользователю не приходилось прокручивать весь путь вниз, чтобы добраться до paginator, если он ищет запись, которая находится в наверх.

Я пытался связать оба пагинатора с одним и тем же источником данных. Но это не сработало. Итак, попытался создать 2 источника данных, но у него также есть одно ограничение.

Единственное ограничение заключается в том, что пагинатор внизу не может изменять элементы на странице, поскольку нет способа, позволяющего мне контролировать это свойство.

Кроме того, я не мог установить индекс страницы или элементы для свойств страницы напрямую (таблица не обновлялась), поэтому все перемещения выполняются с помощью некоторых методов logi c и paginator, таких как 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();
      }
    }
  }

Ответы [ 2 ]

4 голосов
/ 04 апреля 2020

Нет необходимости использовать два пагинатора, которые внесли некоторые изменения в ваш код, пожалуйста, проверьте его.

Вот мой код стекаблиц: - https://stackblitz.com/edit/multiple-paginators-svwwfj

Надеюсь, это помогает!

1 голос
/ 05 апреля 2020

Это решение работает, если вы хотите показывать по одному пагинатору за раз

Чтобы решить вышеуказанную проблему, я создал директиву прокрутки до. В этой директиве я прослушивал события прокрутки и сравнивал window.pageYOffset с элементом nativeElement.offsetTop

if (pageYOffset of window < element's offsetTop). Им устанавливалось свойство showUpperOne Значение true, свойство 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;
  }
}

Я использовал эту директиву для 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" и получил доступ к свойствам директивы показать и скрыть paginators *ngIf="mainDiv.showLowerOne ", *ngIf="mainDiv.showUpperOne" соответственно.

Это покажет или скроет paginators на свитке, но будет проблема с передачей функциональности paginator другому paginator, как только один paginator скрывается. снова установить источник данных.

Чтобы решить эту проблему, я добавил свойство currentPageSize и установил значение по умолчанию 10 currentPageSize=10;. Чтобы переназначить paginator на источник данных, я прослушал события страницы, используя (page)="pageEvents($event)" в шаблоне paginator. И в функции 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

...