[英]Datagrid for nested endpoints in react-admin
I am trying to understand what the right approach would be to address nested endpoints, let's assume I have a many to many books
and authors
relationship, and an API which exposes api/authors
, api/books
, and api/authors/{id}/books
.我试图了解解决嵌套端点的正确方法是什么,假设我有多对多的
books
和authors
关系,以及一个公开api/authors
、 api/books
和api/authors/{id}/books
。 This is a common design pattern.这是一种常见的设计模式。
The CRUD on api/authors
works beautifully in react-admin. api/authors
上的 CRUD 在 react-admin 中工作得很好。 However, under the authors <Show>
I want to show a <Datagrid>
of all the books with pagination and sorting, which my api makes available under api/authors/{id}/books
.但是,在作者
<Show>
我想显示所有带有分页和排序的书籍的<Datagrid>
,我的 api 在api/authors/{id}/books
。
What is the right approach to make a datagrid of such a nested endpoint?制作这种嵌套端点的数据网格的正确方法是什么?
I've looked into the <ReferenceManyField>
which works well in the one to many context but doesn't allow accessing nested endpoints, only filtering an endpoint.我研究了
<ReferenceManyField>
,它在一对多上下文中运行良好,但不允许访问嵌套端点,只过滤端点。
Ideally I would want something that is along the lines of:理想情况下,我想要一些类似的东西:
<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>
Note that <NestedResourceField>
is a hypothetical component which would have a behavior very similar to<ReferenceManyField>
but would accept a nested endpoint under nestedResource
instead of target
.请注意,
<NestedResourceField>
是一个假设的组件,它的行为与<ReferenceManyField>
非常相似,但会接受nestedResource
而不是target
下的嵌套端点。
I am struggling to understand what the design strategy should be for the hypothetical <NestedResourceField>
in order to re-use as much of the react-admin framework as possible.我正在努力理解假设的
<NestedResourceField>
的设计策略应该是什么,以便尽可能多地重用 react-admin 框架。
It would be straightforward to "manually" do the fetch myself and list the content but then I would lose all the pagination, filtering, sorting, etc... that comes with react-admin and the fact that books
is an already defined resource.自己“手动”获取并列出内容会很简单,但是我会丢失所有的分页、过滤、排序等......这与 react-admin 以及
books
是一个已经定义的资源这一事实有关。
My question is similar to these unanswered questions:我的问题类似于这些未回答的问题:
custom routes in react-admin react-admin 中的自定义路由
custom path for resource route in react-admin react-admin 中资源路由的自定义路径
Turns out an almost identical question which I had not found previously was posted here: Support for resource nesting原来我以前没有发现的一个几乎相同的问题在这里发布: 支持资源嵌套
So I decided to solve this with a hack in the dataProvider.所以我决定通过在 dataProvider 中的 hack 来解决这个问题。
Keeping with the above example and using the stockReferenceManyField
:保持上面的例子并使用股票
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>
I then modified my dataProvider, which is a fork of ra-jsonapi-client .然后我修改了我的 dataProvider,它是ra-jsonapi-client 的一个分支。 I changed
index.js
under the case GET_MANY_REFERENCE
from this:我在
case GET_MANY_REFERENCE
的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)}`;
to this:对此:
// 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)}`;
So basically I just remap the parameters to the url for the special case where the target
matches a hard coded regex.所以基本上我只是将参数重新映射到 url 以用于
target
与硬编码正则表达式匹配的特殊情况。
ReferenceManyField
would normally have caused the dataProvider to call api/books?filter[_nested_authors_id]=1
and this modification makes the dataProvider call api/authors/1/books
instead. ReferenceManyField
通常会导致 dataProvider 调用api/books?filter[_nested_authors_id]=1
并且此修改使 dataProvider 改为调用api/authors/1/books
。 It is transparent to react-admin. react-admin 是透明的。
Not elegant but it works and doesn't seem to break anything on the front end.不优雅,但它有效并且似乎没有破坏前端的任何东西。
Try using ArrayField component:尝试使用 ArrayField 组件:
<Show {...props}>
<TabbedShowLayout>
<Tab label="Books">
<ArrayField source="books" label="">
<Datagrid>
<TextField source="name" />
</Datagrid>
</ArrayField>
</Tab>
</TabbedShowLayout>
</Show>
Where books is your nested resource field.其中书籍是您的嵌套资源字段。 In your "author" end point you should include books.
在您的“作者”端点中,您应该包括书籍。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.