Admin-on-REST中为Create动作配置双组件页面的可行方案咨询
嘿,这个需求其实挺常见的,我来给你说说在admin-on-rest里实现多个Create组件页面的正确姿势~
首先,你之前自定义路由失败的核心原因确实是组件没拿到admin上下文里的Resource相关数据(比如dataProvider、resource名称这些),不过有两种靠谱的方式可以解决这个问题:
方法一:利用Resource组件的多Create入口配置(官方推荐)
admin-on-rest的<Resource>组件其实支持把create属性设为一个对象,而不是单一组件,这样就能为同一个Resource配置多个不同的Create页面,而且自动帮你处理上下文传递,不用自己操心。
步骤如下:
定义两个不同的Create组件
先写好你需要的两个创建页面组件,比如一个是视频上传专用,一个是基础信息录入:// 视频上传专用的Create组件 const VideoUploadCreate = (props) => ( <Create {...props}> <SimpleForm> <TextInput source="title" /> <FileInput source="videoFile" label="上传视频" /> {/* 其他上传相关字段 */} </SimpleForm> </Create> ); // 基础信息录入的Create组件 const VideoBasicCreate = (props) => ( <Create {...props}> <SimpleForm> <TextInput source="title" /> <TextInput source="description" multiline /> <NumberInput source="duration" label="时长(秒)" /> {/* 其他基础字段 */} </SimpleForm> </Create> );在Resource中配置多Create入口
把<Resource>的create属性改成一个对象,每个键对应一个自定义路径(比如upload),值就是对应的组件:<Admin dataProvider={dataProvider}> <Resource name="videos" list={VideoList} create={{ main: VideoBasicCreate, // 默认的create入口,路径是/videos/create upload: VideoUploadCreate // 自定义的上传入口,路径是/videos/upload }} /> </Admin>在侧边栏添加对应的菜单入口
自定义侧边栏,把两个Create页面的链接加上,方便用户访问:import { MenuItem, CreateButton, Sidebar } from 'admin-on-rest'; import VideoIcon from '@material-ui/icons/VideoLibrary'; const CustomSidebar = (props) => ( <Sidebar {...props}> <MenuItem to="/videos" primaryText="视频列表" leftIcon={<VideoIcon />} /> {/* 基础创建入口 */} <CreateButton to="/videos/create" label="添加基础视频" /> {/* 上传专用入口 */} <CreateButton to="/videos/upload" label="上传视频" /> </Sidebar> ); // 把自定义侧边栏传给Admin组件 <Admin dataProvider={dataProvider} sidebar={CustomSidebar}> {/* ...Resource配置 */} </Admin>
方法二:自定义路由 + withContext高阶组件
如果你一定要用完全独立的自定义路由,那可以用admin-on-rest提供的withContext高阶组件,把admin的上下文数据(比如dataProvider、resource名称)注入到你的自定义页面组件里,这样Create组件就能拿到必要的Resource数据了。
示例代码:
import { withContext, Create, SimpleForm, TextInput, FileInput } from 'admin-on-rest'; import { Route } from 'react-router-dom'; // 用withContext包裹自定义页面组件,获取admin上下文 const CustomVideoUploadPage = withContext(({ dataProvider, ...props }) => ( <Create dataProvider={dataProvider} resource="videos" // 指定对应的Resource名称 {...props} > <SimpleForm> <TextInput source="title" /> <FileInput source="videoFile" label="上传视频" /> </SimpleForm> </Create> )); // 在Admin中添加自定义路由 <Admin dataProvider={dataProvider}> <Resource name="videos" list={VideoList} create={VideoBasicCreate} /> {/* 自定义上传页面路由 */} <Route path="/videos/upload" component={CustomVideoUploadPage} /> </Admin>
两种方法各有优势:第一种是官方推荐的,完全贴合admin-on-rest的设计,上下文传递自动处理;第二种更灵活,适合需要完全自定义页面结构的场景。你可以根据自己的需求选择~
内容的提问来源于stack exchange,提问作者vascoFG

