如何在admin-on-rest的SimpleForm中用key替代id作为请求标识
如何在admin-on-rest中用key替代id作为请求标识
我之前在基于admin-on-rest开发后台的时候,刚好碰到过和你一模一样的场景——数据主键是key而非默认的id,导致Edit组件请求时总是传undefined。折腾了一阵后终于搞定了,给你分享下完整的实现步骤:
1. 修改List组件的跳转逻辑
默认的EditButton会用记录的id字段生成跳转URL,所以我们需要自定义它,让它用key来替代:
import { List, Datagrid, EditButton, TextField } from 'admin-on-rest'; export const ParamList = props => ( <List title="All params" {...props}> <Datagrid> <TextField source="key" label="Key" /> <TextField source="value" label="Value" /> {/* 自定义EditButton,把record的id映射为key的值 */} <EditButton basePath={props.basePath} record={record => ({ ...record, id: record.key })} /> </Datagrid> </List> );
2. 自定义Edit组件,指定用key作为请求标识
接下来要写一个自定义的Edit组件,它会从URL里拿到key参数,然后把它作为Edit组件的id属性传入,这样请求时就会用key代替默认的id:
import { Edit, SimpleForm, TextInput, required } from 'admin-on-rest'; // 注意:如果你的admin-on-rest版本比较旧,可能需要用props.match.params而不是useParams import { useParams } from 'react-router-dom'; export const ParamEdit = props => { // 从URL参数中获取key const { key } = useParams(); return ( <Edit {...props} id={key} // 核心:把Edit组件的id设置为key,这样请求时就会用它作为标识 recordRepresentation="key" // 可选:让面包屑、标题等地方显示key的值而不是默认的id > <SimpleForm> {/* key作为主键,设置为不可编辑 */} <TextInput source="key" disabled validate={[required()]} /> <TextInput source="value" label="Value" validate={[required()]} /> </SimpleForm> </Edit> ); };
3. 调整数据提供者(Data Provider)适配后端API
如果你的后端API期望请求的路径参数是key而非id,还需要包装一下数据提供者,确保请求URL和参数符合后端要求。比如用simpleRestProvider的话,可以这么改:
import { simpleRestProvider, fetchUtils } from 'admin-on-rest'; const apiUrl = 'https://your-api-endpoint.com'; const baseDataProvider = simpleRestProvider(apiUrl, fetchUtils.fetchJson); // 自定义数据提供者,替换请求中的id为key const customDataProvider = { ...baseDataProvider, // 处理单条数据查询 getOne: (resource, params) => { return fetchUtils.fetchJson( `${apiUrl}/${resource}/${params.id}`, // 这里params.id已经是key的值了,直接用即可 { method: 'GET' } ); }, // 处理更新请求 update: (resource, params) => { return fetchUtils.fetchJson( `${apiUrl}/${resource}/${params.id}`, { method: 'PUT', body: JSON.stringify(params.data), headers: new Headers({ 'Content-Type': 'application/json' }), } ); }, // 处理删除请求(如果需要的话) delete: (resource, params) => { return fetchUtils.fetchJson( `${apiUrl}/${resource}/${params.id}`, { method: 'DELETE' } ); } };
4. 配置路由
最后在Admin组件的Resource配置里,把自定义的Edit组件传进去即可:
import { Admin, Resource } from 'admin-on-rest'; import { ParamList, ParamEdit } from './your-component-path'; const App = () => ( <Admin dataProvider={customDataProvider}> <Resource name="params" list={ParamList} edit={ParamEdit} options={{ label: 'Parameters' }} /> </Admin> ); export default App;
这样一套下来,整个流程就完全用key代替id作为请求标识了:List里的Edit按钮会跳转到带key的URL,Edit组件用这个key发起请求,SimpleForm提交时也会保留key作为主键,后端收到的请求也能正确识别对应的记录。
内容的提问来源于stack exchange,提问作者Lucas Mota
相关产品推荐
相关产品推荐

