Angular Material结合Firebase时表格排序筛选功能异常如何解决
问题修复方案
问题根源
从Firebase拉取返回的单条数据结构为{key: string, val: Product},业务字段title、price都存放在二级属性val下。Angular Material的MatTableDataSource默认的排序、筛选逻辑仅会读取数据对象的一级属性,因此无法匹配到title、price字段,只能识别一级属性key,导致功能异常。
修复方法
只需在admin-products.ts的ngAfterViewInit生命周期中,自定义数据源的排序访问器和筛选规则即可,修改后的完整代码如下:
import { ProductService } from './../../product.service'; import { Component, OnDestroy, ViewChild, AfterViewInit } from '@angular/core'; import { Subscription } from 'rxjs'; import { Product } from 'src/app/models/product'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; import { MatTableDataSource } from '@angular/material/table'; @Component({ selector: 'app-admin-products', templateUrl: './admin-products.component.html', styleUrls: ['./admin-products.component.css'] }) export class AdminProductsComponent implements OnDestroy, AfterViewInit{ products: Product[] = []; subscription: Subscription; displayedColumns: string[] = ['title', 'price', 'edit']; dataSource = new MatTableDataSource<any>(this.products); @ViewChild(MatSort) sort: MatSort | any; @ViewChild(MatPaginator) paginator: MatPaginator | any; constructor(private productService: ProductService) { this.subscription = this.productService.getAll() .subscribe(products => { this.dataSource.data = products; console.log(this.dataSource.data); }); } ngAfterViewInit(){ this.dataSource.sort = this.sort; this.dataSource.paginator = this.paginator; // 自定义排序取值规则 this.dataSource.sortingDataAccessor = (item, property) => { switch(property) { case 'title': return item.val.title.toLowerCase(); case 'price': return item.val.price; default: return item[property as keyof typeof item]; } }; // 自定义筛选匹配规则 this.dataSource.filterPredicate = (data, filter: string) => { const searchStr = filter.trim().toLowerCase(); // 可自行调整需要参与筛选的字段 return data.val.title.toLowerCase().includes(searchStr) || data.val.price.toString().includes(searchStr); }; } applyFilter(event: Event) { const filterValue = (event.target as HTMLInputElement).value; this.dataSource.filter = filterValue.trim().toLowerCase(); } ngOnDestroy(){ this.subscription.unsubscribe(); } }
修改完成后,排序和筛选就会基于title、price字段正常执行。
内容的提问来源于stack exchange,提问作者blurry
相关产品推荐
相关产品推荐

