使用 admin-on-rest 添加嵌套资源
Add Nested resource using admin-on-rest
我正在使用 admin-on-rest。多么棒的框架!它对我的平面资源非常有效。
我正在检索项目列表 /projects
。我已经实现了一个 ProjectEdit 视图来编辑给定的项目 /projects/:id
export const ProjectEdit = props => {
const projectId = props.match.params.id;
return (
<Edit title={<ProjectTitle />} {...props}>
<TabbedForm>
<FormTab label="Project">
<DisabledInput source="id" />
<TextInput source="name" />
</FormTab>
<FormTab label="Companies">
// WHAT Should I put here to edit my companies list ???
</FormTab>
</TabbedForm>
</Edit>
);
};
我想实现一个新选项卡,我可以从中添加/删除项目中的公司。
获取/projects/:id/companies
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 2,
"name": "My Company"
}
]
}
POST /projects/:id/companies
删除/projects/:id/companies/:company_id
我尝试使用 ReferenceManyField
,但我无法配置它,因为我的 API 需要自定义 GET。我的项目没有任何公司参考。我找不到任何关于如何执行它的示例。
有什么线索吗? :)
EDIT1: 我可以使用 显示我的项目公司列表。但我仍然无法在版本中显示它(例如:使用 ReferenceArrayInput + SelectArrayInput)
您必须使用自定义 restClient。我遇到了同样的问题,所以如果您还没有,请创建它。
然后查看数据如何到达您希望为其拥有子资源的每个方法并修改 URL 并请求您从那里开始。
例如,在 GET_MANY_REFERENCE
中,我 target
包含一个指定我正在寻找子资源的 ENUM。
let url = `${apiUrl}/${resource}`;
case GET_MANY_REFERENCE: {
let target;
try {
target = JSON.parse(params.target);
} catch (err) {
target = {};
}
/*
Reference fields do not support the format of
/<resource>/<resource id>/<subresource> so the target parameter is used
to instead indicate the subresource call. See
https://marmelab.com/admin-on-rest/Fields.html#referencefield
for details on reference fields
*/
if (target && target[ENUMS.SUBRESOURCE_IDENTIFIER]) {
/*
If a resource ID is present, it's because the base resource doesn't match the
host resource and needs to use its own ID, not the host resource ID.
*/
if (target[ENUMS.RESOURCE_ID]) {
url = `${url}/${target[ENUMS.RESOURCE_ID]}/${target.subresource}`;
} else {
url = `${url}/${params.id}/${target.subresource}`;
}
}
然后您可以将其扩展到 REST 客户端的其他部分
我找到了解决问题的办法。我对它不是很满意,但它确实有效...我创建了一个 Datagrid 以从项目中删除给定的公司。按钮作为参数 record, resourceId
.
我还添加了一个 ReferenceInput,让我在用户点击 Save
时一次添加一家公司
我使用了自定义 RestClient.js 来处理 GET_MANY_REFERENCE
调用并使用给定的 url 来检索我项目的公司。当用户点击保存以添加新公司时,我对 UPDATE
做了同样的处理。
EditProject.js :
<FormTab label="Entreprises">
<ReferenceManyField label="Entreprises" reference="companies" target={{ resource: "projects", resourceId: projectId, subresource: "companies" }} allowEmpty>
<Datagrid>
<TextField source="id" />
<TextField source="name" />
<RemoveBtn resourceId={projectId} />
</Datagrid>
</ReferenceManyField>
<ReferenceInput label="Company to Add" source="companyToAdd" reference="companies" allowEmpty>
<SelectInput optionText="name" />
</ReferenceInput>
</FormTab>
RemoveBtn.js :
export class RemoveBtn extends React.Component {
handleRemove = () => {
const {record, resourceId } = this.props;
projectsService.removeCompanyFromProject(resourceId, record.id).then(() => window.location.reload());
};
render() {
return <FlatButton label="Retirer" secondary onClick={this.handleRemove} />;
}
}
希望对您有所帮助...
我正在使用 admin-on-rest。多么棒的框架!它对我的平面资源非常有效。
我正在检索项目列表 /projects
。我已经实现了一个 ProjectEdit 视图来编辑给定的项目 /projects/:id
export const ProjectEdit = props => {
const projectId = props.match.params.id;
return (
<Edit title={<ProjectTitle />} {...props}>
<TabbedForm>
<FormTab label="Project">
<DisabledInput source="id" />
<TextInput source="name" />
</FormTab>
<FormTab label="Companies">
// WHAT Should I put here to edit my companies list ???
</FormTab>
</TabbedForm>
</Edit>
);
};
我想实现一个新选项卡,我可以从中添加/删除项目中的公司。
获取/projects/:id/companies
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 2,
"name": "My Company"
}
]
}
POST /projects/:id/companies
删除/projects/:id/companies/:company_id
我尝试使用 ReferenceManyField
,但我无法配置它,因为我的 API 需要自定义 GET。我的项目没有任何公司参考。我找不到任何关于如何执行它的示例。
有什么线索吗? :)
EDIT1: 我可以使用
您必须使用自定义 restClient。我遇到了同样的问题,所以如果您还没有,请创建它。
然后查看数据如何到达您希望为其拥有子资源的每个方法并修改 URL 并请求您从那里开始。
例如,在 GET_MANY_REFERENCE
中,我 target
包含一个指定我正在寻找子资源的 ENUM。
let url = `${apiUrl}/${resource}`;
case GET_MANY_REFERENCE: {
let target;
try {
target = JSON.parse(params.target);
} catch (err) {
target = {};
}
/*
Reference fields do not support the format of
/<resource>/<resource id>/<subresource> so the target parameter is used
to instead indicate the subresource call. See
https://marmelab.com/admin-on-rest/Fields.html#referencefield
for details on reference fields
*/
if (target && target[ENUMS.SUBRESOURCE_IDENTIFIER]) {
/*
If a resource ID is present, it's because the base resource doesn't match the
host resource and needs to use its own ID, not the host resource ID.
*/
if (target[ENUMS.RESOURCE_ID]) {
url = `${url}/${target[ENUMS.RESOURCE_ID]}/${target.subresource}`;
} else {
url = `${url}/${params.id}/${target.subresource}`;
}
}
然后您可以将其扩展到 REST 客户端的其他部分
我找到了解决问题的办法。我对它不是很满意,但它确实有效...我创建了一个 Datagrid 以从项目中删除给定的公司。按钮作为参数 record, resourceId
.
我还添加了一个 ReferenceInput,让我在用户点击 Save
我使用了自定义 RestClient.js 来处理 GET_MANY_REFERENCE
调用并使用给定的 url 来检索我项目的公司。当用户点击保存以添加新公司时,我对 UPDATE
做了同样的处理。
EditProject.js :
<FormTab label="Entreprises">
<ReferenceManyField label="Entreprises" reference="companies" target={{ resource: "projects", resourceId: projectId, subresource: "companies" }} allowEmpty>
<Datagrid>
<TextField source="id" />
<TextField source="name" />
<RemoveBtn resourceId={projectId} />
</Datagrid>
</ReferenceManyField>
<ReferenceInput label="Company to Add" source="companyToAdd" reference="companies" allowEmpty>
<SelectInput optionText="name" />
</ReferenceInput>
</FormTab>
RemoveBtn.js :
export class RemoveBtn extends React.Component {
handleRemove = () => {
const {record, resourceId } = this.props;
projectsService.removeCompanyFromProject(resourceId, record.id).then(() => window.location.reload());
};
render() {
return <FlatButton label="Retirer" secondary onClick={this.handleRemove} />;
}
}
希望对您有所帮助...