理解 Angular Material Table

Angular Material Table 是 Angular Material 的自带组件,

用于生成 Material 样式的表格。

Angular Material Table 使用维护十分灵活,

但是其使用方法相对原生 HTML Table 较为繁琐。

包括导入模块、设置表格数据源、表格/列设定、表格/行设定四个步骤。

1.设置表格数据源

表格数据源即表格将要展现的数据。

import {Component} from '@angular/core';

export interface PeriodicElement {
  name: string;
  position: number;
  weight: number;
  symbol: string;
}

const ELEMENT_DATA: PeriodicElement[] = [
  {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'},
  {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'},
  {position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li'},
  {position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be'},
  {position: 5, name: 'Boron', weight: 10.811, symbol: 'B'},
  {position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C'},
  {position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N'},
  {position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O'},
  {position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F'},
  {position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne'},
];

/**
 * @title Basic use of `<table mat-table>`
 */
@Component({
  selector: 'table-basic-example',
  styleUrls: ['table-basic-example.css'],
  templateUrl: 'table-basic-example.html',
})
export class TableBasicExample {
  ...
  dataSource = ELEMENT_DATA;
}

如上代码所示,

我们在 TableBasicExample 组件中,定义了一个公有变量 dataSource。

它是一个 PeriodicElement 类型的对象数组。

然后在组件对应的 HTML 中,将其赋值给 mat-table 的 dataSource 属性。

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">

  ...

</table>

2.表格之列设定

定义完表格的数据源之后,需要完成表格之列设定。

即列名变量、列名、列内容。

为了便于理解,可以先看下图展示的一个完整 Material Table.

其中蓝色方框标注的是列名,由 mat-header-cell 定义

其中红色方框标注的是列内容, 列内容由 mat-cell 定义。

列名变量由 matColumnDef 定义,但是没有在前端显示,

其具体作用后面会提到,可以暂且放一下。

通过配合使用,可以完成列上内容的和列头的定义,如下所示。

<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">


  <!-- Position Column -->
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef> No. </th>
    <td mat-cell *matCellDef="let element"> {{element.position}} </td>
  </ng-container>
   
  ....

</table>

下面对这三个指令分别进行介绍。

2.1. matColumnDef

定义列名变量。一般在步骤 3 中确定列顺序时对列引用。

2.2. mat-header-cell 与 *matHeaderCellDef

mat-header-cell 与 *matHeaderCellDef

前者控制该列 header 样式,后者控制 header 显示名称。

若无 mat-header-cell 不会有 material 样式,

若无 *matHeaderCellDef 会导致运行时错误。

<th mat-header-cell *matHeaderCellDef> No. </th>

这里将某列的列名定义为了 No.

2.3. mat-cell 与 *matCellDef

mat-cell 与 *matCellDef

前者控制该列每个单元格样式,后者控制该列单元格与数据源哪个字段绑定。

若无 mat-cell 不会有 material 样式,

若无 *matCellDef 会导致运行时错误。

<td mat-cell *matCellDef="let element"> {{element.position}} </td>

这里的 let element 定义了一个 dataSource 中的一个对象,

通过指定 element.position,就可以在该列上全部显示为 posistion 的值。

返回步骤 1 看看,

这个 position 是不是就正好是 dataSource 对象数组中对象的属性呢。

3.表格之行设定

这在文档中也被称为“行模板”(row templates)。

在此处可以定义列的显示顺序及以行的特定动作,比如点击之后的路由。

由 mat-header-row 和 mat-header-row 两个指令指定。

其中 displayedColumns 中定义的列名,

必须与 matColumnDef 定义的列名相互对应。

...
@Component({
  selector: 'table-basic-example',
  styleUrls: ['table-basic-example.css'],
  templateUrl: 'table-basic-example.html',
})
export class TableBasicExample {
  ...
  displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
}
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">


  <!-- Position Column -->
  <ng-container matColumnDef="position">
    <th mat-header-cell *matHeaderCellDef> No. </th>
    <td mat-cell *matCellDef="let element"> {{element.position}} </td>
  </ng-container>
   
  ....

  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

3.1. mat-header-row 与 *matHeaderRowDef

mat-header-row 与 *matHeaderRowDef

前者定义了表头是否出现,后者定义了表头上各列名的显示顺序。

两者缺一均无法正常显示表头。

我们把它和 2.1 中 matColumnDef 结合起来看。

 <!-- Position Column -->
 <ng-container matColumnDef="position">
  ...
 </ng-container>
displayedColumns: string[] = ['position', 'name', 'weight', 'symbol'];
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>

是否发现,

matColumnDef 中的 ‘position’ 就是 displayedColumns 中定义的’postion’,

这样,

假如你想改变标题的显示顺序,

你只要修改 displayedColumns 中的那几个变量变量的顺序就可以了。

3.2. mat-row 与 *matRowDef

mat-row 与 *matRowDef

前者定义了所有行上单元格样式,后者定义了所有行上单元格的显示顺序。

两者缺一不可。

<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>

可以看到,熟悉的 displayedColumns 又在这里出现了,

它也指定了行方向上单元格中对应列的显示顺序。

这个一般来说需要和列名顺序一致,因此这里都是用了 displayedColumns。

4.在线例子

总的来说,Angular Material 并不是一个非常好上手的组件,

设计的也过于冗余和复杂。

因此推荐还是结合官方文档提供的一个在线示例 ,以及本教程共同来理解。

参考文献

Angular Material Data Table: A Complete Example (Server Pagination, Filtering, Sorting)

发表评论

电子邮件地址不会被公开。 必填项已用*标注