Как синхронизировать размеры страниц mat-paginator?

Я пытаюсь синхронизировать размеры страниц нескольких мат-пагинаторов, вложенных в несколько дочерних компонентов.

Я использую общий сервис для хранения «глобального» размера страницы.

Однако размер страницы обновляется во всех мат-пагинаторах, но фактический размер страницы пагинаторов не меняется.

Общий сервис:

import { EventEmitter, Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";

@Injectable({
   providedIn: 'root'
 })
 export class PaginatorService {
   private pageSizeSubject = new BehaviorSubject<number>(10); // Default page size
   pageSize$ = this.pageSizeSubject.asObservable();
 
   setPageSize(pageSize: number) {
     this.pageSizeSubject.next(pageSize);
   }
 }

Компонент дочерней таблицы

<table mat-table [dataSource] = "propertiesDataSource" multiTemplateDataRows class = "mat-elevation-z0" id = "properties-table" matSort>   
   <ng-container *ngFor = "let column of propertiesTableColumns" [matColumnDef] = "column">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>{{ tableHeader[column] }}</th>
      <td mat-cell *matCellDef = "let lease">
          <ng-container [ngSwitch] = "column">
              <span *ngSwitchDefault>{{ lease[column] }}</span>
          </ng-container>
      </td>
  </ng-container>

   <tr mat-header-row *matHeaderRowDef = "propertiesTableColumns; sticky:true"></tr>
   <tr mat-row *matRowDef = "let property; columns: propertiesTableColumns" (click) = "openProperty(property)" class = "item-row"></tr> 
</table>
<mat-paginator [pageSizeOptions] = "[10,25,50,100]" [pageSize] = "pageSize" (page) = "onPageSizeChange($event)" showFirstLastButtons>
</mat-paginator>
export class LocationDetailPropertyTableComponent implements OnInit, AfterViewInit {
   @Input() properties: PropertyDtoModel[] = [];
   @Input() locationCustomerID: number;
   @Input() dateFilter: Date = new Date();

   @ViewChild(MatPaginator) paginator: MatPaginator;

   public propertiesDataSource: MatTableDataSource<PropertyDtoModel> = new MatTableDataSource();
   public propertiesTableColumns = Object.keys(eTableHeader) as Array<keyof typeof eTableHeader>;
   public tableHeader = eTableHeader;
   public pageSize: number;

   constructor(
      private router: Router,
      private rentersLegalLiabilityService: RentersLegalLiabilityService,
      private paginatorService: PaginatorService,
      private chageDetectorRef: ChangeDetectorRef
   ) {}

   ngAfterViewInit(): void {
      this.propertiesDataSource.paginator = this.paginator;
   }

   ngOnInit() {
      this.propertiesDataSource = new MatTableDataSource(this.properties);

      this.paginatorService.pageSize$.subscribe(size => {
         this.pageSize = size;
         this.chageDetectorRef.detectChanges(); // Manually trigger a change detection
      });
   }

   onPageSizeChange(event: any) {
      this.paginatorService.setPageSize(event.pageSize);
    }

Компонент родительской страницы

<table mat-table [dataSource] = "locationDataSource" multiTemplateDataRows class = "mat-elevation-z0" id = "locations-table" matSort>
   <!-- column for Expand button -->
   <ng-container matColumnDef = "ExpandButton">
      <th mat-header-cell *matHeaderCellDef></th>
      <td mat-cell *matCellDef = "let location" (click) = "$event.stopPropagation()">
         <button mat-icon-button (click) = "expandedLocation=expandedLocation===location ? null : location"
            matTooltip = "Expand">
            <span class = "mat-button-wrapper">
               <mat-icon>
                  {{expandedLocation === location ? "expand_more": "chevron_right"}}
               </mat-icon>
            </span>
         </button>
      </td>
      <td mat-foter-cell *matFooterCellDef></td>
   </ng-container>
   
   <ng-container *ngFor = "let header of tableHeaders" [matColumnDef] = "header.key">
      <th mat-header-cell *matHeaderCellDef mat-sort-header>{{ header.label }}</th>
      <td mat-cell *matCellDef = "let location">{{ location[header.key] }}</td>
      <td mat-footer-cell *matFooterCellDef>{{ getFooterContent(header) }}</td>
   </ng-container>

   <!-- Expanded content column -->
   <ng-container matColumnDef = "expandedDetail">
      <td mat-cell *matCellDef = "let location" [attr.colspan] = "locationsTableColumns.length">
         <div [@detailExpand] = "location == expandedLocation ? 'expanded' : 'collapsed'">
            <location-detail-property-table [properties] = "location.LocationProperties" [locationCustomerID] = "location.LocationCustomerID" [dateFilter] = "dateFilter"></location-detail-property-table>
         </div>
      </td>
   </ng-container>

   <tr mat-header-row *matHeaderRowDef = "locationsTableColumns; sticky:true"></tr>
   <tr mat-row *matRowDef = "let location; columns: locationsTableColumns" class = "item-row"></tr>
   <tr mat-row *matRowDef = "let row; columns: ['expandedDetail']" class = "detail-row"></tr>
   <tr mat-footer-row *matFooterRowDef = "locationsTableColumns"></tr>
</table>

Я пытался принудительно обнаружить изменения, но безуспешно. После изменения нумерации страниц с 10 до 25 в другой расширенной таблице все остальные пагинаторы также должны быть обновлены до размера страницы 25.

Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
0
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

IIRC MatTableDataSource реагирует только на излучаемые PageEvents, и простое изменение свойства pageSize не генерирует эти события.

Таким образом, вам придется либо вручную вычислить правильную новую страницу и обновить page или pageIndex на пагинаторе, чтобы она генерировала событие, либо вы можете использовать встроенный метод _changePageSize(pageSize), который вычислит новый индекс страницы таким образом, чтобы гарантировать первый элемент. на странице будет по-прежнему отображаться при применении pageSize, а затем генерировать событие новой страницы. Я думаю, что _changePageSize(pageSize) уже запускает обнаружение изменений, поэтому вы также сможете удалить его:

  this.paginatorService.pageSize$.subscribe(size => {
     this._changePageSize(size);
  });

Вот работающий упрощенный образец на stackblitz

Я смог выполнить эту работу. Спасибо за вашу помощь. Единственное, над чем мне пришлось поработать, — это предотвратить бесконечный цикл событий, поскольку я обнаруживал изменения в pageSize с помощью события (page) в mat-paginator.

Andrew Biddle 18.07.2024 15:28

Другие вопросы по теме