问题描述
<FilterList
label="Sales"
icon={<AttachMoneyIcon />}
>
<FilterListItem
label="Best Sellers"
value={{
sales: 10
}}
/>
<FilterListItem
label="Average Sellers"
value={{
sales_lte: 25,sales_gt: 10,sales: undefined,}}
/>
<FilterListItem
label="Low Sellers"
value={{
sales_lte: 10,sales_gt: 0,}}
/>
<FilterListItem
label="Never Sold"
value={{
sales_lte: undefined,sales_gt: undefined,sales: 0,}}
/>
</FilterList>
上面的代码片段取自 react-admin 演示 站点。他们使用支持后缀“gte”和“lte”的自定义数据提供程序来过滤大于等于或小于等于的值 来自数据库。因此,FilterListItem
Component
有一个名为 'value' 的道具,它采用键值对,即 'sales_lte' 、'sales_gte',过滤销售额 '大于等于' 或 '小于等于'。我想知道如何使用 react-admin-firebase Data Provider 以类似方式进行过滤。
Link to React-admin-firebase Github
解决方法
ra-data-firebase 不支持 Greater_than 或 lower_than 运算符。他们的过滤逻辑(参见https://github.com/benwinding/react-admin-firebase/blob/fb58f58515ee45a43fa92a4acc0f262fe721366a/src/misc/arrayHelpers.ts#L42-L91)只测试相等性。
但是,如果您愿意使用一些低级 Firebase API,这似乎是可能的(请参阅 https://github.com/benwinding/react-admin-firebase/issues/161#issuecomment-729314143):
test("FirebaseClient with filter gte",async () => {
const testDocs = [
{
title: "A",obj: {volume: 100},},{
title: "B",obj: {volume: 101},{
title: "C",obj: {volume: 99},}
];
const collName = "list-filtered";
const collection = fire.db().collection(collName);
await Promise.all(testDocs.map((doc) => collection.add(doc)));
const client = new FirebaseClient(fire,{});
const result = await client.apiGetList(collName,{
filter: {
collectionQuery: (c: firebase.firestore.CollectionReference) => c.where('obj.volume','>=',100)
},pagination: {
page: 1,perPage: 10,sort: {
field: "obj.volume",order: "ASC",});
const third = result.data.length as any;
expect(third).toBe(2);
},100000);
,
我从他们的 github 页面 React Admin Firebase Github 下载了 React-admin-firebase npm 源并修改了如下所示的代码,它可以工作。我对过滤器名称进行了硬编码,但我们可以轻松实现它,以便它接受以“_gte”或“_lte”结尾的任何过滤器名称。
1. 在 Vscode(或任何其他编辑器)中打开下载的源代码并打开位于“src/”中的名为“paramsToQuery.ts”的文件provider/lazy-loading/paramsToQuery.ts'
2. 搜索函数“filtersToQuery”并进行相应的更改,如下面的代码所示:
export function filtersToQuery(
query: Query,filters: { [fieldName: string]: any }
): Query {
Object.keys(filters).forEach((fieldName) => {
if (fieldName === 'sales_gte') {
query = query.where(fieldName.split('_')[0],filters[fieldName]);
} else if (fieldName === 'sales_lte') {
query = query.where(fieldName.split('_')[0],'<=',filters[fieldName]);
} else {
query = query.where(fieldName,'==',filters[fieldName]);
}
});
return query;
}
- 使用 npm 在本地将其链接到您的项目。