用于react-admin中嵌套端点的Datagrid

时间:2019-07-05 18:24:25

标签: reactjs react-admin

我试图了解解决嵌套端点的正确方法,假设我具有多对多的booksauthors关系,以及一个暴露api/authors的API ,api/booksapi/authors/{id}/books。这是一种常见的设计模式。

api/authors上的CRUD在react-admin中表现出色。但是,在作者<Show>下,我想显示所有书中的<Datagrid>的分页和排序方式,我的api在api/authors/{id}/books下提供了这些内容。

采用这种嵌套端点的数据网格的正确方法是什么?

我研究了<ReferenceManyField>,它在一对多上下文中效果很好,但是不允许访问嵌套端点,只能过滤端点。

理想情况下,我想要符合以下条件的东西:

<Show {...props}>
    <TabbedShowLayout>
        <Tab label="Books">
            <NestedResourceField reference="books" nestedResource={`authors/${props.record.id}/books`} pagination={<Pagination/>} >
                <Datagrid>
                    <TextField source="name" />
                </Datagrid>
            </NestedResourceField>
        </Tab>
    </TabbedShowLayout>
</Show>

请注意,<NestedResourceField>是一个假设的组件,其行为与<ReferenceManyField>非常相似,但将接受nestedResource下的嵌套端点,而不是target

我正在努力了解假设的<NestedResourceField>的设计策略,以便重用尽可能多的react-admin框架。

直接“手动”进行自我获取并列出内容将很简单,但随后我将失去react-admin附带的所有分页,过滤,排序等...以及{{1} }是已经定义的资源。

我的问题类似于以下未回答的问题:

custom routes in react-admin

custom path for resource route in react-admin

编辑

在这里发布了一个我以前从未发现过的几乎相同的问题: Support for resource nesting

2 个答案:

答案 0 :(得分:0)

因此,我决定通过对dataProvider进行破解来解决此问题。

保留上面的示例并使用股票ReferenceManyField

<Show {...props}>
    <TabbedShowLayout>
        <Tab label="Books">
            <ReferenceManyField reference="books" target="_nested_authors_id" pagination={<Pagination/>} >
                <Datagrid>
                    <TextField source="name" />
                </Datagrid>
            </ReferenceManyField>
        </Tab>
    </TabbedShowLayout>
</Show>

然后,我修改了我的dataProvider,它是ra-jsonapi-client的分支。 我从index.js下更改了case GET_MANY_REFERENCE

      // Add the reference id to the filter params.
      query[`filter[${params.target}]`] = params.id;

      url = `${apiUrl}/${resource}?${stringify(query)}`;

对此:

      // Add the reference id to the filter params.
      let refResource;
      const match = /_nested_(.*)_id/g.exec(params.target);
      if (match != null) {
        refResource = `${match[1]}/${params.id}/${resource}`;
      } else {
        query[`filter[${params.target}]`] = params.id;
        refResource = resource;
      }

      url = `${apiUrl}/${refResource}?${stringify(query)}`;

因此,基本上,我只是将特殊情况下的参数重新映射到url,其中target与硬编码的正则表达式匹配。

ReferenceManyField通常会导致dataProvider调用api/books?filter[_nested_authors_id]=1,而此修改使dataProvider调用api/authors/1/books。对react-admin来说是透明的。

不太优雅,但它可以正常工作,而且前端似乎没有任何损坏。

答案 1 :(得分:0)

尝试使用ArrayField组件:

<Show {...props}>
    <TabbedShowLayout>
        <Tab label="Books">
            <ArrayField source="books" label="">
              <Datagrid>
                 <TextField source="name" />
              </Datagrid>
            </ArrayField>
        </Tab>
    </TabbedShowLayout>
</Show>

书籍在哪里是您的嵌套资源字段。在您的“作者”终点,您应该包括书籍。