react-admin 中嵌套端点的数据网格

Datagrid for nested endpoints in react-admin

我试图了解解决嵌套端点的正确方法是什么,假设我有一个多对多 booksauthors 关系,以及一个 API公开 api/authorsapi/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 框架。

"manually" 自己获取并列出内容会很简单,但是我会失去所有的分页、过滤、排序等...... react-admin 和事实books 是已定义的资源。

我的问题类似于这些未回答的问题:

custom routes in react-admin

编辑

原来这里发布了一个我以前没有发现的几乎相同的问题:

所以我决定通过修改 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 的一个分支。 我把 case GET_MANY_REFERENCE 下的 index.js 改成了:

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

是透明的

不够优雅,但它可以工作,而且似乎没有破坏前端的任何东西。

尝试使用 ArrayField 组件:

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

其中 books 是您的嵌套资源字段。在你的 "author" 终点你应该包括书籍。