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

如何通过ngx-daterangepicker-material筛选MatTable数据源?

Angular 实现 ngx-daterangepicker-material 联动 MatTable 数据刷新

下面分两种场景,用 Observable 实现日期变化监听与表格数据更新:

场景一:本地筛选现有表格数据

基于已加载的全量数据,根据选中的日期范围做本地过滤:

  1. 初始化核心变量
    在组件中定义存储日期范围的 BehaviorSubject(用于持续监听变化),以及表格数据源和原始全量数据:

    import { Component, OnInit } from '@angular/core';
    import { MatTableDataSource } from '@angular/material/table';
    import { BehaviorSubject, combineLatest, of } from 'rxjs';
    import { map } from 'rxjs/operators';
    
    interface YourDataType {
      id: number;
      dateField: string; // 假设数据中的日期字段是字符串格式
      // 其他字段...
    }
    
    @Component({
      selector: 'app-your-component',
      templateUrl: './your-component.component.html',
      styleUrls: ['./your-component.component.css']
    })
    export class YourComponent implements OnInit {
      // 存储选中的日期范围,初始值为null(表示未筛选)
      private dateRange$ = new BehaviorSubject<{ start: Date; end: Date } | null>(null);
      // 原始全量数据(可从API初始化加载)
      originalData: YourDataType[] = [];
      // MatTable数据源
      dataSource = new MatTableDataSource<YourDataType>([]);
      // 表格列定义
      displayedColumns: string[] = ['id', 'dateField', /* 其他列 */];
    
      ngOnInit(): void {
        // 模拟加载全量数据(实际项目中可从API获取)
        this.originalData = [
          { id: 1, dateField: '2024-05-01' },
          { id: 2, dateField: '2024-05-10' },
          { id: 3, dateField: '2024-05-15' }
        ];
    
        // 组合日期范围和原始数据,实时生成筛选后的数据
        combineLatest([this.dateRange$, of(this.originalData)])
          .pipe(
            map(([range, data]) => {
              if (!range) return data; // 无日期范围时返回全量数据
              // 根据日期范围过滤数据
              return data.filter(item => {
                const itemDate = new Date(item.dateField);
                return itemDate >= range.start && itemDate <= range.end;
              });
            })
          )
          .subscribe(filteredData => {
            this.dataSource.data = filteredData; // 更新表格数据源
          });
      }
    
      // 日期选择器变化时触发的事件
      onDateRangeChange(range: { startDate: Date; endDate: Date }): void {
        this.dateRange$.next({ start: range.startDate, end: range.endDate });
      }
    }
    
  2. 模板中的日期选择器绑定
    模板里绑定日期变化事件:

    <input
      type="text"
      ngxDaterangepickerMd
      [(ngModel)]="selectedDateRange"
      (datesUpdated)="onDateRangeChange($event)"
      [locale]="{ applyLabel: '确定', cancelLabel: '取消' }"
    />
    
    <table mat-table [dataSource]="dataSource">
      <!-- 列定义 -->
      <ng-container matColumnDef="id">
        <th mat-header-cell *matHeaderCellDef>ID</th>
        <td mat-cell *matCellDef="let element">{{element.id}}</td>
      </ng-container>
      <!-- 其他列... -->
      <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
      <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
    </table>
    

场景二:通过API请求新数据刷新表格

每次日期范围变化时,发起API请求获取对应数据,更新表格:

  1. 组件核心逻辑
    利用 switchMap 将日期范围的变化转换成API请求,自动取消未完成的旧请求:

    import { Component, OnInit } from '@angular/core';
    import { MatTableDataSource } from '@angular/material/table';
    import { BehaviorSubject, filter, switchMap } from 'rxjs';
    import { YourDataService } from './your-data.service';
    
    interface YourDataType {
      id: number;
      dateField: string;
      // 其他字段...
    }
    
    @Component({
      selector: 'app-your-component',
      templateUrl: './your-component.component.html',
      styleUrls: ['./your-component.component.css']
    })
    export class YourComponent implements OnInit {
      private dateRange$ = new BehaviorSubject<{ start: Date; end: Date } | null>(null);
      dataSource = new MatTableDataSource<YourDataType>([]);
      displayedColumns: string[] = ['id', 'dateField', /* 其他列 */];
    
      constructor(private dataService: YourDataService) {}
    
      ngOnInit(): void {
        // 监听日期范围变化,发起API请求
        this.dateRange$
          .pipe(
            filter(range => !!range), // 仅当有有效日期范围时发起请求
            switchMap(range => {
              // 将Date对象转为API需要的格式(比如ISO字符串)
              const startStr = range.start.toISOString();
              const endStr = range.end.toISOString();
              return this.dataService.fetchDataByDateRange(startStr, endStr);
            })
          )
          .subscribe(apiData => {
            this.dataSource.data = apiData; // 用API返回的新数据更新表格
          });
    
        // 可选:初始化时加载默认日期范围的数据
        this.dateRange$.next({
          start: new Date('2024-05-01'),
          end: new Date()
        });
      }
    
      onDateRangeChange(range: { startDate: Date; endDate: Date }): void {
        this.dateRange$.next({ start: range.startDate, end: range.endDate });
      }
    }
    
  2. API请求服务示例
    定义数据服务封装HTTP请求:

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    
    interface YourDataType {
      id: number;
      dateField: string;
      // 其他字段...
    }
    
    @Injectable({ providedIn: 'root' })
    export class YourDataService {
      constructor(private http: HttpClient) {}
    
      fetchDataByDateRange(start: string, end: string): Observable<YourDataType[]> {
        return this.http.get<YourDataType[]>('/api/your-data-endpoint', {
          params: { start, end } // 传递日期范围参数给后端
        });
      }
    }
    

关键注意点

  • 使用 BehaviorSubject 是因为它会保存当前最新值,新订阅者能立即获取到当前的日期范围,确保表格初始状态正确。
  • switchMap 会自动取消之前未完成的API请求,避免旧的响应覆盖新数据,适合频繁触发的请求场景。
  • 本地筛选时要注意日期格式的一致性,确保数据中的日期能正确转为 Date 对象进行比较。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 15:25:20