iT邦幫忙

2024 iThome 鐵人賽

DAY 6
0
Modern Web

用 Angular Material 開發應用程式系列 第 6

Day 6 - 分頁與排序

  • 分享至 

  • xImage
  •  

今天來在工作事項資料表元件上加入分頁與排序功能。

Paginator

相較於我們在使用 ng add 命令產生 Table 元件時,Schematics 把分頁元件實體放至資料來源,我比較傾向單純在資料來源記錄每頁筆數與當前頁碼,來降低資料處理與介面操作之間的耦合。

export class TaskDataSource extends DataSource<TaskItem> {
  readonly pageIndex = signal(0);
  readonly pageSize = signal(10);
  readonly totalCount = signal(0);
  ...
}

因此,在引用 MatPaginatorModule 之後,就可以利用 <mat-paginator> 標籤使用分頁元件。如下面程式,在分頁元件中將 lengthpageSizepageIndex 等參數設定與資料來源的屬性連結。另外,我們可以透過 pageSizeOptions 來讓使用者選擇不同的每頁筆數,如果想關閉這個功能則可以設定 hidePageSizetrue

<mat-paginator
  [length]="dataSource.totalCount()"
  [pageIndex]="dataSource.pageIndex()"
  [pageSize]="dataSource.pageSize()"
  [pageSizeOptions]="[5, 10, 25, 100]"
  showFirstLastButtons="true"
  (page)="onPageChange($event)"
/>

當使用者切換每頁筆數或是點選上下頁時,就可以利用 page 事件來取得新增資訊。

onPageChange({ pageIndex, pageSize }: PageEvent): void {
  this.dataSource.pageIndex.set(pageIndex);
  this.dataSource.pageSize.set(pageSize);
}

其他屬性的部分,Paginator 元件只提供上下頁的按鈕,也可以設定 showFirstLastButton 屬性來開啟第一頁與最後一頁的按鈕,但若要使用顯示每一個頁碼的需求,就只能自行開發了。

https://ithelp.ithome.com.tw/upload/images/20240920/20109645cY9MJsFlOZ.png

從上面可看到,Paginator 元件的預設的語系會是英文,如果希望使用其他語系或是修正元件的文字,可以建立一類別來實作 MatPaginatorIntl 介面。

@Injectable()
export class CustomPaginatorIntl implements MatPaginatorIntl {
  changes = new Subject<void>();

  firstPageLabel = '第一頁';
  itemsPerPageLabel = '每頁筆數';
  lastPageLabel = '最後一頁';
  nextPageLabel = '下一頁';
  previousPageLabel = '上一頁';

  getRangeLabel(page: number, pageSize: number, length: number): string {
    if (length === 0) {
      return '第 1 頁 / 共 1 頁';
    }
    const amountPages = Math.ceil(length / pageSize);
    return `第 ${page + 1} 頁 / 共 ${amountPages} 頁`;
  }
}

接著,就可以在 app.config 來抽換 MatPaginatorIntl 提供者的實作。

export const appConfig: ApplicationConfig = {
  providers: [
    ...
    { provide: MatPaginatorIntl, useClass: CustomPaginatorIntl },
  ],
};

https://ithelp.ithome.com.tw/upload/images/20240920/20109645466FhBC3Cu.png

Sort

Angular Material 把排序的實作獨立出來,在引用 MatSortModule 模組後,我們可以在一般的資料表中使用 matSortmat-sort-header 指令元件。

<table matSort (matSortChange)="sortData($event)">
  <tr>
    <th>編號</th>
    <th mat-sort-header="subject">主旨</th>
    <th>內容</th>
  </tr>
  ...
</table>

如上面程式,在一般表格中使用 mat-sort-header 會指定要排序的對象;然而,如果使用在 MatTable 之中,則會以 matColumnDef 的設定為主。

<table
  mat-table
  [dataSource]="dataSource"
  aria-label="Elements"
  matSort
  (matSortChange)="onSortChange($event)"
>
  <ng-container matColumnDef="subject">
    <th mat-header-cell *matHeaderCellDef mat-sort-header>主旨</th>
    <td mat-cell *matCellDef="let row">{{ row.subject }}</td>
    <td mat-footer-cell *matFooterCellDef="">主旨表尾</td>
  </ng-container>
  ...
</table>

當使用者選擇要排序的欄位時,就可以利用 matSortChange 事件,把排序資訊設定到資料來源內,以觸發後續的資料重整。

https://ithelp.ithome.com.tw/upload/images/20240920/201096457WjvGEEgMY.png

本日範例

接下來

今天完成以資料表方式來呈現工作事項的清單,接下來我們使用卡片來呈現工作事項。


上一篇
Day 5 - 資料表清單
下一篇
Day 7 - 卡片
系列文
用 Angular Material 開發應用程式30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言