Angular Material Pagination 條件渲染

問題描述

使用 Angular Material 的 mat-paginator 元件時,如果將其放在 @if*ngIf 條件渲染區塊內,會導致分頁器功能失靈。

相關參考資料:

錯誤用法

以下做法會導致分頁器失效:

@if(eventListFiltered.length > 0) {
  <mat-paginator
    [pageSizeOptions]="[5, 10]"
    aria-label="Select page of users"
  ></mat-paginator>
}

或使用舊版 Angular 的 *ngIf 指令:

<mat-paginator
  *ngIf="eventListFiltered.length > 0"
  [pageSizeOptions]="[5, 10]"
  aria-label="Select page of users"
></mat-paginator>

正確用法

應該使用 [hidden] 屬性來控制分頁器的顯示和隱藏:

<div [hidden]="eventListFiltered.length === 0">
  <mat-paginator
    [pageSizeOptions]="[5, 10]"
    aria-label="Select page of users"
  ></mat-paginator>
</div>

原因說明

這個問題發生的原因是:

  1. 使用 @if*ngIf 時,元素不會被加入到 DOM 中

  2. Angular Material 的分頁器在初始化時需要進行一些 DOM 操作和事件監聽

  3. 當條件變為 true,分頁器加入 DOM 時,它可能無法正確初始化或連接到數據源

而使用 [hidden] 屬性只是在視覺上隱藏元素,但元素仍存在於 DOM 中,所以分頁器能夠正確初始化和運作。

其他解決方案

除了使用 [hidden] 屬性外,還有其他幾種處理方式:

1. 使用 CSS 控制顯示

<mat-paginator
  [style.display]="eventListFiltered.length === 0 ? 'none' : 'block'"
  [pageSizeOptions]="[5, 10]"
></mat-paginator>

2. 創建一個包裝元件

將 MatPaginator 封裝在自定義元件中,並在該元件內處理條件顯示邏輯。

3. 使用 *ngIf 但確保分頁器重新初始化

// 在元件中
resetPaginator() {
  if (this.paginator) {
    this.paginator.firstPage();
    // 其他必要的重置操作
  }
}
<ng-container *ngIf="eventListFiltered.length > 0">
  <mat-paginator
    #paginator
    [pageSizeOptions]="[5, 10]"
  ></mat-paginator>
</ng-container>

最佳實踐

  • 避免使用 @if*ngIf 來條件性顯示 Angular Material 的分頁器

  • 優先使用 [hidden] 屬性控制分頁器的顯示和隱藏

  • 確保分頁器總是能正確接收到數據源的變化

  • 在資料載入完成後再顯示分頁器,避免初始化問題

這樣的處理方式不僅能解決在沒有資料時隱藏分頁器的需求,還能確保分頁功能正常運作。

Last updated