【问题标题】:Access Property of a Nested Record嵌套记录的访问属性
【发布时间】:2020-08-25 12:16:31
【问题描述】:

我正在使用带有api-platform/admin 2.1.1 的 React-Admin 3.5.0。

我的资源之一有一个自定义列表。
该资源有一个title 和一个author。作者有几个属性,其中一个是username

按照documentation,我尝试在我的列表中显示作者的用户名,如下所示:

export const MyList = (props) =>
    <List {...props}>
        <Datagrid>
            <TextField source="title" />
            <TextField source="author.username" />
        </Datagrid>
    </List>

这不起作用。 author.username 的字段为空。

我查了一下,发现记录只包含作者的ID:

record:
    ...
    title: "abcde"
    author: "/users/1"

但是,来自服务器的响应确实包含用户名属性:

0: {
    ...,
    "title": "abcde",
    "author": {
        "@id": "/users/1",
        "username": "Test"
    }
},
...

有什么好办法让它工作吗?

【问题讨论】:

    标签: react-admin api-platform.com


    【解决方案1】:

    在 api-platform 管理源代码上找到了这个:

    用 IRI 替换嵌入的对象,并将对象本身存储在 在不发出新的 HTTP 请求的情况下重用缓存。

    就在下面:

    document[key] = document[key]['@id'];
    

    https://github.com/api-platform/admin/blob/ba0630083f28eaa8806bc1da4613677924604a52/src/hydra/dataProvider.js#L75

    此行为来自此拉取请求:

    https://github.com/api-platform/admin/pull/96

    要显示作者字段,您需要为每个字段使用一个 ReferenceField:

    export const MyList = (props) =>
        <List {...props}>
            <Datagrid>
                <TextField source="title" />
                <ReferenceField source="author" reference="users">
                    <TextField source="username"/>
                </ReferenceField>
    
                <ReferenceField source="author" reference="users" link={false}>
                    <TextField source="email"/>
                </ReferenceField>
            </Datagrid>
        </List>
    

    这样做会使作者字段链接到作者页面。您可以在 ReferenceField 上禁用此传递链接={false},例如上面的第二个作者字段

    React 管理员会将所有这些作者引用请求打包成一个,因此即使 api-platform 数据提供者不履行缓存承诺,您最终也只会收到一个 http 请求。

    注意:您必须为参考资源添加&lt;Resource&gt; - react-admin 需要它来获取参考数据。如果您想在侧边栏菜单中隐藏它,您可以省略此参考中的 list 属性。

    【讨论】:

      【解决方案2】:

      2.2 版应该支持嵌套/嵌入对象:

      https://api-platform.com/docs/admin/handling-relations/#display-a-field-of-an-embedded-relation

      我试过了。不幸的是,它对我不起作用...

      import {
          fetchHydra
          HydraAdmin,
          hydraDataProvider as baseHydraDataProvider,
      } from "@api-platform/admin";
      
      const dataProvider = baseHydraDataProvider(
          entrypoint,
          fetchHydra,
          apiDocumentationParser,
          true // use embedded!
      );
      
      export default () => (
          <HydraAdmin
              dataProvider={dataProvider} authProvider={authProvider} entrypoint={entrypoint} i18nProvider={i18nProvider}>
              <ResourceGuesser name={"users"} list={UserList} icon={UserIcon}/>
               ....
          </HydraAdmin>
      

      如何调试

      将转换后的记录数据记录到您的控制台中(这会导致一些错误,但至少您可以看到实际发生的情况)。

      const TagsField = ({record, ...props}) => (
          <ArrayField source="images">
              {console.log("Record:")}
              {console.log(record)}
              <TextField source="image"/>
          </ArrayField>
      )
      ... 
      export const HouseList = (props) => (
      <ListGuesser title="houses" {...props}>
          ....
          <NumberField source="price" label="Price (€)"/>
          <TagsField label="Images" source="images" sortable={false}>
          </TagsField>
          ....
      

      有人知道我在这里做错了什么吗?

      更多细节

      https://github.com/api-platform/admin/pull/299

      【讨论】:

      • 嘿,谢谢!这实际上对我有用,并且是比 ReferenceField 更好的解决方案,因为不涉及额外的加载时间。也许在您的情况下它不起作用,因为它是一组图像而不是单个图像?
      • 刚刚检查了 GitHub 拉取请求。 “如果它是一个嵌入数组,则之前的行为保持不变:对象被它们的 IRI 替换,并且在 FieldGuesser 和 InputGuesser 中使用引用。”
      【解决方案3】:

      我创建了 PR 来添加对嵌入数组的支持:https://github.com/api-platform/admin/pull/302

      它将在下一个版本中(一个补丁)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-12
        • 2015-01-01
        • 1970-01-01
        • 2019-03-12
        • 2018-06-03
        相关资源
        最近更新 更多