如何通过ngx-daterangepicker-material筛选MatTable数据源?
Angular 实现 ngx-daterangepicker-material 联动 MatTable 数据刷新
下面分两种场景,用 Observable 实现日期变化监听与表格数据更新:
场景一:本地筛选现有表格数据
基于已加载的全量数据,根据选中的日期范围做本地过滤:
初始化核心变量
在组件中定义存储日期范围的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 }); } }模板中的日期选择器绑定
模板里绑定日期变化事件:<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请求获取对应数据,更新表格:
组件核心逻辑
利用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 }); } }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
相关产品推荐
相关产品推荐

