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

Angular通用动态列表格多列自定义filterPredicate实现求助

动态列通用表格的多列过滤实现方案

我需要实现一个通用Angular Material表格组件,核心需求是:

  • 接收tableColumns(动态列配置)和dataSource(原始数据)作为@Input()
  • 支持为每列添加独立的过滤输入框
  • 已完成过滤表单的FormGroup初始化,能获取到各列的过滤值,但不清楚如何基于动态列实现通用过滤逻辑。试过管道和网上的固定列过滤方案,但都不适用动态列场景。

当前代码实现

HTML模板

<table mat-table [dataSource]="tableDataSource">
  <ng-container *ngFor="let col of tableColumns; let i = index" [matColumnDef]="col.key">
    <ng-container>
      <th class="header" mat-header-cell *matHeaderCellDef>
        <span *ngIf="!col.config">
          {{ col['display'] }}
        </span>
        <form [formGroup]="form">
          <mat-form-field *ngIf="!col.config" class="filter">
            <input matInput placeholder="Filter" formControlName="{{tableColumns[i].key}}">
          </mat-form-field>
        </form>
      </th>
      <td mat-cell *matCellDef="let element; let row"> 
        <ng-container>
          {{ element[col.key] }}
        </ng-container>   
      </td>
    </ng-container>
  </ng-container>
  <tr mat-header-row *matHeaderRowDef="keys"></tr>
  <tr mat-row *matRowDef="let row; columns: keys"></tr>
</table>

TS组件代码

import { Component, Input, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { MatTableDataSource } from '@angular/material/table';

interface GenericTableColumn {
  key: string;
  display: string;
  config?: any;
}

@Component({
  selector: 'app-generic-table',
  templateUrl: './generic-table.component.html',
  styleUrls: ['./generic-table.component.css']
})
export class GenericTableComponent implements OnInit {
  @Input() tableColumns: GenericTableColumn[] = []
  @Input() dataSource: Array<object> = []
  form!: FormGroup;
  tableDataSource!: MatTableDataSource<any>;
  keys!: string[];

  ngOnInit(): void {
    this.keys = this.tableColumns.map(col => col.key);
    this.initFormControls();
    this.initTableDataSource();
    this.registerFormChangeListener();
  }

  initFormControls() {
    const formGroup: FormGroup = new FormGroup({});
    this.tableColumns.forEach((column) => {
      if (column.key !== 'actions') {
        const control: FormControl = new FormControl('');
        formGroup.addControl(column.key, control);
      }
    });
    this.form = formGroup;
  }
}

示例数据与期望结果

原始数据源

const sampleDataSource = [
  { "id": "1", "name": "someValue1", "someOtherKey": "someOtherValue" },
  { "id": "2", "name": "someValue2", "someOtherKey": "someOtherValue2" },
  { "id": "3", "name": "someValue3", "someOtherKey": "someOtherValue2" }
];

过滤表单值

const filterValues = { "id": "", "name": "someValue1", "someOtherKey": "someOtherValue2" };

期望过滤结果

const filteredResults = [
  { "id": "1", "name": "someValue1", "someOtherKey": "someOtherValue" },
  { "id": "2", "name": "someValue2", "someOtherKey": "someOtherValue2" }
];

完整解决方案

1. 初始化带过滤功能的数据源

添加initTableDataSource方法,将原始数据转为MatTableDataSource并配置动态过滤逻辑:

initTableDataSource() {
  this.tableDataSource = new MatTableDataSource(this.dataSource);
  // 自定义动态过滤谓词
  this.tableDataSource.filterPredicate = (row: any, filter: string) => {
    const filterObj = JSON.parse(filter);
    // 遍历所有过滤条件,仅保留非空条件的匹配
    return Object.keys(filterObj).every(key => {
      const filterValue = filterObj[key];
      if (!filterValue) return true;
      // 不区分大小写的模糊匹配,可根据需求调整匹配规则
      const rowValue = String(row[key]).toLowerCase();
      return rowValue.includes(filterValue.toLowerCase());
    });
  };
}

2. 监听表单变化触发过滤

添加registerFormChangeListener方法,订阅表单值变化事件,触发表格过滤:

registerFormChangeListener() {
  this.form.valueChanges.subscribe(filterObj => {
    // 过滤掉不需要的列(如actions列)
    const validFilterObj = Object.fromEntries(
      Object.entries(filterObj).filter(([key]) => 
        this.tableColumns.some(col => col.key === key && col.key !== 'actions')
      )
    );
    // 将过滤对象转为JSON字符串,传递给表格数据源
    this.tableDataSource.filter = JSON.stringify(validFilterObj);
  });
}

3. 模板修正

将模板中的[dataSource]="dataSource"改为[dataSource]="tableDataSource",确保使用带过滤功能的数据源。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:41:06