React-admin多对多关联数据在Datagrid的展示方案问询
在React-Admin的中展示多对多关联(含中间表)的Subjects
嘿,我刚好处理过类似的场景,给你两种实用的解决方案,都能实现你要的类似<SingleFieldList>的标签式展示效果~
方法一:后端返回嵌套数据(最省心的方案)
如果能控制后端接口的话,这绝对是首选!让后端在返回group数据的时候,把关联的subject以及中间表group_subject的属性一起嵌套回来。比如后端返回的group结构可以是这样:
{ "id": 1, "name": "编程基础组", "group_subjects": [ { "rubrics": "核心课程", "schedule": "周一 9:00-11:00", "subject": { "id": 101, "name": "JavaScript入门" } }, // 更多关联的科目项 ] }
这样前端直接用<ArrayField>配合<SingleFieldList>就能轻松渲染:
import { Datagrid, TextField, ArrayField, SingleFieldList, ChipField } from 'react-admin'; export const GroupList = () => ( <List> <Datagrid rowClick="edit"> <TextField source="id" /> <TextField source="name" /> {/* 展示关联的科目 */} <ArrayField source="group_subjects"> <SingleFieldList> <ChipField source="subject.name" label="关联科目" /> {/* 如果要展示中间表的属性,比如上课时间,直接加个ChipField就行 */} {/* <ChipField source="schedule" /> */} </SingleFieldList> </ArrayField> </Datagrid> </List> );
方法二:前端通过关联查询拼接数据
如果后端没法调整接口,只能分别获取三张表的数据,那我们可以通过ReferenceArrayField先关联中间表,再嵌套ReferenceField关联subject表:
import { Datagrid, TextField, ReferenceArrayField, SingleFieldList, ChipField, ReferenceField } from 'react-admin'; export const GroupList = () => ( <List> <Datagrid rowClick="edit"> <TextField source="id" /> <TextField source="name" /> {/* 先关联中间表group_subjects */} <ReferenceArrayField reference="group_subjects" target="group_id"> <SingleFieldList> {/* 再通过中间表关联subject表 */} <ReferenceField reference="subjects" source="subject_id" link={false}> <ChipField source="name" /> </ReferenceField> {/* 要展示中间表的rubrics或schedule?直接加ChipField就好 */} {/* <ChipField source="rubrics" /> */} </SingleFieldList> </ReferenceArrayField> </Datagrid> </List> );
这里要注意两个关键点:
ReferenceArrayField的reference是中间表group_subjects,target是中间表里关联group的字段(比如group_id)ReferenceField里的link={false}是为了避免点击标签跳转到科目详情页,如果你需要跳转的话去掉这个属性就行
进阶:自定义组件展示更多信息
要是你想同时展示科目名称和中间表的属性(比如rubrics和上课时间),可以自己写个自定义组件代替ChipField:
import { makeStyles } from '@material-ui/core/styles'; import Chip from '@material-ui/core/Chip'; const useStyles = makeStyles({ chip: { margin: '2px', fontSize: '0.8rem', }, }); const SubjectWithMetaChip = ({ record }) => { const classes = useStyles(); return ( <Chip className={classes.chip} label={`${record.subject.name} | ${record.rubrics} | ${record.schedule}`} variant="outlined" /> ); }; // 然后在ArrayField里用这个组件: <ArrayField source="group_subjects"> <SingleFieldList> <SubjectWithMetaChip /> </SingleFieldList> </ArrayField>
这样就能完美实现你要的类似<SingleFieldList>的标签式展示,还能灵活包含中间表的额外属性哦!
内容的提问来源于stack exchange,提问作者oskrgg
相关产品推荐
相关产品推荐

