简体   繁体   English

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

[英]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 .我试图了解解决嵌套端点的正确方法是什么,假设我有多对多的booksauthors关系,以及一个公开api/authorsapi/booksapi/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 中资源路由的自定义路径

Edit编辑

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM