这是我为我们的项目编写的 dataProvider。所有的过滤、排序、分页都是在客户端完成的。
import { fetchUtils, DataProvider } from 'ra-core';
const dataProvider = (apiUrl : string, httpClient = fetchUtils.fetchJson) : DataProvider => ({
getList: async (resource, params) => {
const { json } = await httpClient(`${ apiUrl }/${ resource }`);
const feedFilter = params.filter["feed"];
const stateFilter = params.filter["state"];
const result = json
.filter(e => {
if (!feedFilter) {
return true;
}
return e.feed.includes(feedFilter.toUpperCase());
})
.filter(e => {
if (!stateFilter) {
return true;
}
return e.state === stateFilter;
});
const { field, order } = params.sort;
result.sort(dynamicSort(field, order));
const { page, perPage } = params.pagination;
const showedResult = result.slice((page - 1) * perPage, page * perPage);
return {
data: showedResult.map((resource : { feed : string; }) => ({ ...resource, id: resource.feed })),
total: result.length,
};
},
getMany: async (resource) => {
const url = `${ apiUrl }/${ resource }`;
const { json } = await httpClient(url);
return ({
data: json.map((resource : { feed : string; }) => ({ ...resource, id: resource.feed })),
});
},
getManyReference: async (resource) => {
const url = `${ apiUrl }/${ resource }`;
const { headers, json } = await httpClient(url);
return ({
data: json.map((resource : { feed : string; }) => ({ ...resource, id: resource.feed })),
total: parseInt(headers.get('X-Total-Count') || "", 10),
});
},
getOne: (resource, params) =>
httpClient(`${ apiUrl }/${ resource }/${ params.id }`).then(({ json }) => ({
data: json,
})),
update: (resource, params) =>
httpClient(`${ apiUrl }/${ resource }/${ params.id }`, {
method: 'PUT',
body: JSON.stringify(params.data),
}).then(({ json }) => ({ data: json })),
updateMany: async (resource, params) => {
const { json } = await httpClient(`${ apiUrl }/${ resource }`, {
method: 'PUT',
body: JSON.stringify(params.data),
});
return ({ data: json });
},
create: (resource, params) =>
httpClient(`${ apiUrl }/${ resource }`, {
method: 'POST',
body: JSON.stringify(params.data),
}).then(({ json }) => ({
data: { ...params.data, id: json.id },
})),
delete: (resource, params) =>
httpClient(`${ apiUrl }/${ resource }/${ params.id }`, {
method: 'DELETE',
}).then(({ json }) => ({ data: json })),
deleteMany: async (resource, params) => {
const { json } = await httpClient(`${ apiUrl }/${ resource }`, {
method: 'DELETE',
body: JSON.stringify(params.ids),
});
return ({ data: json });
},
});
function dynamicSort(property : string, order : string){
let sortOrder = 1;
if (order === "DESC") {
sortOrder = -1;
}
return function (a : any, b : any){
let aProp = a[property];
let bProp = b[property];
if (!a.hasOwnProperty(property)) {
aProp = ''
}
if (!b.hasOwnProperty(property)) {
bProp = ''
}
const result = (aProp < bProp) ? -1 : (aProp > bProp) ? 1 : 0;
return result * sortOrder;
}
}
const cacheDataProviderProxy = (dataProvider : any, duration = 5 * 60 * 1000) =>
new Proxy(dataProvider, {
get: (dataProvider, name) => (resource : string, params : any) => {
if (name === 'getOne' || name === 'getMany' || name === 'getList') {
return dataProvider.name(resource, params).then((response : { validUntil : Date; }) => {
const validUntil = new Date();
validUntil.setTime(validUntil.getTime() + duration);
response.validUntil = validUntil;
return response;
});
}
return dataProvider.name(resource, params);
},
});
export default cacheDataProviderProxy(dataProvider);