使用admin-on-rest添加嵌套资源

时间:2017-11-17 10:15:24

标签: reactjs admin-on-rest

我正在使用admin-on-rest。多棒的框架!它对我的平板资源非常有效。

我正在检索项目列表/projects。我已经实施了ProjectEdit View来编辑给定的项目/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:我可以使用@malisbad answer显示项目公司的列表。但是我仍然无法在版本中显示它(例如:使用ReferenceArrayInput + SelectArrayInput)

2 个答案:

答案 0 :(得分:3)

您必须使用自定义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客户端的其他部分

答案 1 :(得分:2)

我找到了解决问题的方法。我对它并不满意,但它确实有效......我创建了一个Datagrid来从项目中删除给定的公司。按钮为logging.INFO。{/ p>

我还添加了一个ReferenceInput,让我在用户点击record, resourceId时添加一家公司

我使用自定义RestClient.js来处理Save调用并使用给定的url来检索我的项目公司。当用户点击“保存”添加新公司时,我已经完成同样的操作GET_MANY_REFERENCE

EditProject.js:

UPDATE

RemoveBtn.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>

希望它有所帮助...