Angular MaterialでTableの基本をおさらい

# はじめに

先日、仕事でAngular Materialのテーブルコンポーネントの実装に取り組んだところ、予想以上に理解に時間がかかりました。特に、`MatTableDataSource`の使い方やテンプレートでの列の定義方法など、なかなか把握が難しい部分がありました。同じように実装に取り組む方の参考になればと思い、基本的な実装方法をまとめてみました。

# 前提条件

✓ Angularプロジェクトがセットアップされていること  
✓ Angular Materialがインストールされていること

# 1. 必要なモジュールのインポート

`src/app/table/table.component.ts`
```typescript
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatTableDataSource } from '@angular/material/table';
import { MatTableModule } from '@angular/material/table';

@Component({
  standalone: true,
  imports: [CommonModule, MatTableModule]
})
```

## 実装のポイント
`MatTableDataSource`は、Angular Materialが提供するテーブルのデータ管理と操作機能を包括的に提供するクラスです。データの保持という基本的な機能だけでなく、検索機能、列ヘッダーのクリックによるソート機能、大量のデータを扱う際に便利なページネーションなど、データテーブルに必要な制御機能が実装されています。これらの機能は必要に応じて`MatSort`や`MatPaginator`といった専用のコンポーネントと組み合わせることで有効化できます。

![](https://storage.googleapis.com/zenn-user-upload/c11eb9c7e19b-20250223.png)


# 2. コンポーネントの実装

`src/app/table/table.component.ts`
```typescript
export class TableComponent implements OnInit {
  // 表示する列の定義
  displayedColumns = ['id', 'name', 'email', 'age'];
  
  // データソースの初期化
  dataSource = new MatTableDataSource<UserData>();

  ngOnInit() {
    // サンプルデータの設定
    this.dataSource.data = [
      { id: 1, name: '田中太郎', email: 'tanaka@example.com', age: 25 },
      { id: 2, name: '山田花子', email: 'yamada@example.com', age: 30 }
    ];
  }
}

// データモデルの定義
interface UserData {
  id: number;
  name: string;
  email: string;
  age: number;
}
```

## 実装のポイント

**データ構造の定義**  
`interface UserData`と`MatTableDataSource<UserData>`は、インターフェースでデータ構造を定義し、それをデータソースのジェネリック型として使用します。これにより型安全性が確保され、コード補完が効くようになり、開発時のミスを防ぎます。

**表示列の設定**  
`displayedColumns`では、テーブルに表示する列を配列で定義します。

**データの初期化とMatTableDataSourceの使用**  
`MatTableDataSource`のインスタンスは`dataSource`プロパティとして保持し、実際のデータは`dataSource.data`に設定します。MatTableDataSourceクラスはAngular Materialが提供するデータソースクラスで、テーブルのデータ管理機能（フィルタリング、ソート、ページネーション）を提供します。

# 3. テンプレートの実装

`src/app/table/table.component.html`
```html
<div class="table-container">
  <table mat-table [dataSource]="dataSource">
    <!-- ID列 -->
    <ng-container matColumnDef="id">
      <th mat-header-cell *matHeaderCellDef> ID </th>
      <td mat-cell *matCellDef="let row"> {{row.id}} </td>
    </ng-container>

    <!-- 名前列 -->
    <ng-container matColumnDef="name">
      <th mat-header-cell *matHeaderCellDef> 名前 </th>
      <td mat-cell *matCellDef="let row"> {{row.name}} </td>
    </ng-container>

    <!-- メール列 -->
    <ng-container matColumnDef="email">
      <th mat-header-cell *matHeaderCellDef> メール </th>
      <td mat-cell *matCellDef="let row"> {{row.email}} </td>
    </ng-container>

    <!-- 年齢列 -->
    <ng-container matColumnDef="age">
      <th mat-header-cell *matHeaderCellDef> 年齢 </th>
      <td mat-cell *matCellDef="let row"> {{row.age}} </td>
    </ng-container>

    <!-- ヘッダー行とデータ行の定義 -->
    <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
    <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
  </table>
</div>
```

## 実装のポイント

**テーブルの基本構造**
テーブルは`mat-table`ディレクティブを使用して定義します。`[dataSource]`プロパティバインディングによって、表示するデータを`MatTableDataSource`から受け取ります。

**列の定義**
`displayedColumns`配列で表示する列を指定し、それに対応する`matColumnDef`ディレクティブで各列の実際の表示内容を定義します。これにより、配列で指定した順序でテーブルの列が表示されます。

**セルの定義**  
Angularのテンプレート構文を活用して列ごとのセルを定義します。まずヘッダー行のセルを`mat-header-cell`と`*matHeaderCellDef`で定義し、データ行のセルを`mat-cell`と`*matCellDef`で定義します。データ行では`let row`テンプレート変数を介して各行のデータにアクセスできます。この変数を使うことで、テンプレート内で行データのプロパティを`{{row.name}}`のように参照できます。

# おわりに
本記事では、Angular Materialのテーブルコンポーネントの基本的な実装方法について解説しました。ここで紹介した実装方法を基礎として、さらにソート機能やページネーション機能を追加したり、行のクリックイベントを実装したりすることで、より高度な機能を持つデータテーブルを作成できます。

また機会があれば、実装してみてください。