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

IT技术 reactjs react-admin
2021-05-22 16:39:38

我想了解什么是正确的办法是解决嵌套的终点,让我们假设我有一个多对多booksauthors关系,以及API暴露api/authorsapi/booksapi/authors/{id}/books这是一种常见的设计模式。

CRUD onapi/authors在 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 以及books已经定义的资源这一事实

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

react-admin 中的自定义路由

react-admin 中资源路由的自定义路径

编辑

原来我以前没有发现的一个几乎相同的问题在这里发布: 支持资源嵌套

2个回答

所以我决定通过在 dataProvider 中进行 hack 来解决这个问题。

保持上面的例子并使用股票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.jscase 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/booksreact-admin 是透明的。

不优雅,但它有效并且似乎没有破坏前端的任何东西。

尝试使用 ArrayField 组件:

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

其中书籍是您的嵌套资源字段。在您的“作者”端点中,您应该包括书籍。