问题描述
设置::角度9.1.7,角度材料9.2.3,macOS 10.14.6,ngrx-store / ngrx-data / ngrx-entity 9.1.2
情况:
我有一个功能正常的工作表,其数据源为MatTableDataSource类型,该数据源是从ngrx商店提供的异步HTTP请求中获得的。 我可以使用内置的数据源过滤器功能来过滤Resource本身的所有属性。
问题:
在我的材料表组件中,我没有显示所有的资源属性,某些列显示的是为特定资源属性异步加载的相关数据,例如:{{(element.orderId | orderContactProperty: 'email') | async}}
-资源(元素)具有一个{{ 1}}属性,并且我还从同一台服务器加载“订单和联系人”,这有时会通过管道加载该资源的该订单的联系人并显示其属性(“电子邮件”)。现在,这显然不属于Resource类型的数据源,而是在以后加载,这意味着无法对其进行过滤。
同时过滤不属于原始数据源的这些延迟加载的属性的最佳/最简单的解决方案是什么?基本上,我该如何过滤客户在表格中看到的内容?
什么可行?
我查看了mat-table-exporter扩展名,因为仅导出了可见表数据,我的想法是提取包含所有可见数据的行,然后进行过滤,然后仅使用过滤后的元素更新数据源,但是似乎是一种破解方法,对吗?
我还考虑过通过在显示相关属性并将其添加到相应行之前解析相关属性来“扩展”数据源,以便现在将它们包括在内以进行过滤-那样也没有问题,因为那时资源类型不正确再后来,当我要编辑/更新资源并将其保存到服务器时,我将拥有不需要的属性
但是在将我的时间投入到这些想法中的任何一个之前,是否有人建议/指导如何最好地解决这个问题?我当然不是第一个偶然发现它的人,但是找不到描述该确切场景的任何其他问题
不幸的是,由于它的复杂性以及作为一个客户项目,我无法提供它,但是我希望此屏幕截图有助于说明我的问题:(红色星号表示:不在数据源中并且无法过滤,其他的都可以正常工作)
解决方法
我遇到了完全相同的情况,很惊讶没有找到合适的异步过滤数据的解决方案。 由于 filterPredicate 期望 boolean 作为返回类型,因此不可能以干净的方式将 Observable 从存储选择器合并到数据源。
因此,我决定在本地缓存 store 中的数据(在我的例子中是用户名),并扩展默认的 angular material filterPredicate。
这只有效,因为我已经在实际显示表格之前加载了数据,这限制了这种方法的用例。
filterPredicate: ((data: Data,filter: string) => boolean) = (data: Data,filter: string): boolean => {
// default angular material filter predicate
const dataStr = Object.keys(data).reduce((currentTerm: string,key: string) =>
{
return currentTerm + (data as {[key: string]: any})[key] + '◬';
},'').toLowerCase();
// Transform the filter by converting it to lowercase and removing whitespace.
const transformedFilter = filter.trim().toLowerCase();
const defaultResult = dataStr.indexOf(transformedFilter) !== -1;
// no need to continue searching after a match
if (defaultResult) {
return true;
}
// no match found yet,check usernames for matches
const userIds = this.getUserIds(transformedFilter);
return userIds.includes(data.userId);
}
然后可以将此函数分配给数据源的 filterPredicate,如 https://material.angular.io/components/table/overview#filtering 中所述。
this.dataSource.filterPredicate = this.filterPredicate;
我知道这也不是一个干净的解决方案,但对于我的场景来说已经足够了。欢迎任何更好的方法!