You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 17中能否将基于Signal的数据源用于Material Table(mat-table)?

Angular 17中用Signal作为Material Table数据源的可行性及实现

完全可以将基于Signal的数据作为Angular Material Table的数据源,Angular 17搭配对应版本的@angular/material(>=17.0.0)已经原生支持这种用法。

直接绑定Signal返回值

你尝试的<table mat-table [dataSource]="store.users()">写法本身是可行的,只要Signal返回的是数组类型,表格就能正常渲染。当Signal的值更新时,只要确保更新操作触发了Signal的变化通知(比如用set设置新数组,或用mutate修改内部数组),表格会自动刷新。

示例代码:

定义Signal数据源

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

interface User {
  id: number;
  name: string;
  email: string;
}

export class UserStore {
  private _users = signal<User[]>([]);
  // 对外暴露只读Signal
  readonly users = this._users.asReadonly();

  // 更新数据:传入新数组
  setUsers(newUsers: User[]) {
    this._users.set(newUsers);
  }

  // 新增用户:通过mutate修改内部数组
  addUser(user: User) {
    this._users.mutate(users => users.push(user));
  }
}

模板中绑定

<table mat-table [dataSource]="store.users()">
  <!-- 定义列 -->
  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef> 用户名 </th>
    <td mat-cell *matCellDef="let user"> {{ user.name }} </td>
  </ng-container>

  <ng-container matColumnDef="email">
    <th mat-header-cell *matHeaderCellDef> 邮箱 </th>
    <td mat-cell *matCellDef="let user"> {{ user.email }} </td>
  </ng-container>

  <!-- 表头和行渲染 -->
  <tr mat-header-row *matHeaderRowDef="['name', 'email']"></tr>
  <tr mat-row *matRowDef="let row; columns: ['name', 'email'];"></tr>
</table>

结合MatTableDataSource使用(支持排序/过滤)

如果需要用到Material Table的排序、过滤等高级功能,可以将Signal的值同步到MatTableDataSource中,通过effect监听Signal变化来更新数据源:

import { Component, effect, inject } from '@angular/core';
import { MatTableDataSource } from '@angular/material/table';
import { UserStore } from './user.store';

@Component({
  selector: 'app-user-table',
  templateUrl: './user-table.component.html',
})
export class UserTableComponent {
  private userStore = inject(UserStore);
  displayedColumns = ['name', 'email'];
  dataSource = new MatTableDataSource<User>([]);

  constructor() {
    // 监听Signal变化,同步到数据源
    effect(() => {
      this.dataSource.data = this.userStore.users();
    });
  }
}

模板绑定示例:

<table mat-table [dataSource]="dataSource" matSort>
  <!-- 列定义 -->
  <ng-container matColumnDef="name">
    <th mat-header-cell *matHeaderCellDef mat-sort-header> 用户名 </th>
    <td mat-cell *matCellDef="let user"> {{ user.name }} </td>
  </ng-container>

  <!-- 其他列... -->
  <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
  <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>

注意事项

  • 确保@angular/material版本与Angular 17匹配(建议使用^17.0.0版本),避免版本不兼容导致的问题。
  • 更新Signal数据时,要么传入新数组(set方法),要么使用mutate修改内部数组,这样才能触发Signal的更新通知,让表格同步刷新。

内容的提问来源于stack exchange,提问作者Abdulaziz Ladan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:22:35