Angular Material Mat Table 快速上手心得
本文為介紹個人在使用ng material中的mat table上的一點心得。
我的angular版本為V11, 時間為20201219.
範例如下
架構
說明一下整個html檔的架構,
第1行的dataSource 就是資料源
第2–5,6–9行則是可以理解為兩個column 的模板(template)
第10行則是決定要顯些哪些column模板的標題(header)
第11行是決定要顯些哪些column模板的內容(Cell)
Column 模板
可以看到每個column 有3種以上的directive, 如下:
- matColumnDef: 該column的識別Id,不能與其他column的ID重覆
<ng-container matColumnDef="age"> // columnId為age
- matHeaderCellDef:該column的標題欄內容
<th mat-header-cell *matHeaderCellDef> Age </th> // 該column的首欄內容
- matCellDef:顯示該column 中的cell 的內容
下面的例子中,就是宣告表格的每筆資料為people object, 該column 則顯示people的age 屬性
<td mat-cell *matCellDef="let people"> {{people.age}} </td>
上面只有column 的模板,實際是怎樣把資料套用到模板上呢?
實際把資料套用到模板
實際上表格內容的填入是由以下的程式碼填寫的
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
matHeaderRowDef
顯示標題列(header row)中要顯示的column,displayedColumns是一個string 陣列,其中的column字串要在matColumnDef出現過
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>displayedColumns = ['age', 'Name'];
matRowDef
決定普通資料列中要顯示的column, displayedColumns是一個string 陣列,其中的column字串要在matColumnDef出現過
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
這個例子中,matHeaderRowDef 和 matRowDef 的值剛好一樣,都是displayedColumns,實際上可以不一樣。
displayedColumns是一個string[],其中每個元素就是上面column定義的ID。舉例來說:displayedColumns = ['age', 'name'];
在顯示column標題(header)時
1. Angular會根據matHeaderRowDef 的值,即displayedColumns = [‘age’, ‘name’], 去找對應的column 模板
2. 再從對應模板中找mat-header-cell的值來顯示
如下圖
在顯示column內容時,也是一樣的步驟
1. Angular會根據matRowDef 的值去找對應的column 模板
2. 再從對應模板中找mat-cell的值來顯示
整理一下,Angular 會根據
- matHeaderRowDef
- matRowDef
- matFooterRowDef (本文沒有介紹)
中定義的column陣列(例子中的displayColumns),找到該column中對應的
- mat-header-cell
- mat-cell
- mat-footer-cell
來顯示。
每個mat-column只能有一個mat-header-cell、mat-cell和mat-footer-cell,第二個相同的將不會顯示。
所以若要製作多層header或多層footer,可以為每層header或footer製作各自的column。
到目前為止,應該大概明白table是怎樣長出來,接下來要介紹資料來源。
表格的資料來源 dataSource
<table mat-table [dataSource]="dataSource">
- 最簡單的方式就是一個陣列,陣列中每個元素就是一個Object,object中的key就是column. 如上述的例子,可以提供
dataSource : Person [] = [
{Name: "peter", age: 15},
{Name: "marry", age: 20},
]
- 第2個方法是提供一個每次都傳整個table的Observable
personSubject = new BehaviorSubject<Person[]>([]);
- 官方推薦的方法:提供一個 DataSource類別的實例
DataSource 類別其實就一個有兩個 functions的object:
connect
:dataSource接收到資料時會呼叫
disconnect
: dataSource 刪除資料時會呼叫
可以自己實作
- 官方有內建MatTableDataSource 類別, 支援內建的sort, 分頁,filter 功能
這時資料要放在data 成員上。
dataSource = new MatTableDataSource<Person[]>();
dataSource.data = [];
總結
可以看到標題列, 普通資料列中都有顯示column的設定,即用戶可以在標題列中與普通資料列中顯示不一樣的column。
用戶需在matColumnDef中定義所有column,但最後可以不顯示其中某些column。
相信明白原理後可以輕易做出新增或刪除column的功能!
refer:
- 官方ng material mat-table文件:https://material.angular.io/components/table/overview