如何解析字符串化的 JSON 字段并使用 react-admin 呈现结果
How to parse a stringified JSON field and render results with react-admin
我正在使用带有 Amplify 的 react-admin。我的一种 graphql 类型有一个 AWSJSON 字段,其中包含一个 batchJob 的状态数组。我希望此数组显示在数据网格中,用户可以展开该数据网格以查看批次中每个项目的结果。
数据从 API 返回为字符串化 JSON。我如何才能 JSON.parse 将数据传递给 ArrayField 以在我的 list/show 组件中由 Datagrid 呈现?
该字段的内容如下所示:
[{"reference":"11134","status":"OK"},{"reference":"10278","status":"OK"}]
更新:下面的答案是在我将数据模型稍微更新为:
[{"id": "somerandomuid", "clientReference":"11134","status":"OK"}]
我的代码如下所示:
架构:
type JobTask
@model
@auth(
rules: [
{ allow: owner }
{ allow: groups, groups: ["admins"] }
]
) {
id: ID!
results: AWSJSON
status: String
expiryDate: AWSTimestamp! @ttl
}
显示组件:
export const TaskShow = (props) => {
return (
<Show title={props.header} {...props}>
<SimpleShowLayout>
<Datagrid expand={<ResultsPanel />}>
<TextField
key={cuid()}
fullWidth={true}
source="id"
label="Batch Id"
/>
<TextField
key={cuid()}
fullWidth={true}
source="status"
label="Status"
/>
</Datagrid>
</SimpleShowLayout>
</Show>
);
结果面板组件:
const ResultsPanel = (props) => {
console.log(props)
let resultsArray = JSON.parse(JSON.parse(props.record.results));
console.log(resultsArray);
return (
<>
{resultsArray.map((result) => {
return (
<ArrayField>
<Datagrid>
<TextField source="reference" />
<TextField source="status" />
</Datagrid>
</ArrayField>
);
})}
</>
);
};
但我得到的只是:
我想我会 post 将我的发现提供给可能正在为此苦苦挣扎的任何其他人。
Datagrid 需要上下文,列表组件将为它提供上下文,但由于这是在显示组件中,我试图使用数组来提供上下文。
ArrayField 组件需要一个 source prop,该 prop 必须是精确映射到 API 响应中的 field/property 的字符串;它 不能 是任意的 object/array。然而,字符串映射到的 属性 必须是一个数组,并且无法告诉组件在使用它之前处理 field/property 的内容。所以 Arrayfield 作为上下文提供者退出了。
由于 Array 不适用于我的数据结构,我想我可以使用 RA 的 listcontextprovider,它没有很好的文档记录,但似乎确实允许您构建可由数据网格使用的上下文,如据我所知。但是当我将它与正确的道具一起使用时,它总是给我一个错误(据我所知,无论如何 - 正如我所说,文档有点稀疏)。
最后,我放弃了原生 RA 组件,因为它不适合我的用例,而是编写了一个自定义字段组件来代替我需要的(即从记录中解析字段并将数组传递给要呈现的数据网格)。我使用了本机 MUI 数据网格,它非常有用:
const ResultsPanel = (props) => {
let resultsArray = JSON.parse(JSON.parse(props.record.results));
let columns = [
{ field: "id", headerName: "Item Id", flex: 1 },
{ field: "clientReference", headerName: "Your Reference", flex: 1 },
{ field: "status", headerName: "Import Status", flex: 1 },
];
return (
<div style={{ height: 400, width: "100%" }}>
<DataGrid columns={columns} rows={resultsArray} />
</div>
);
};
我正在使用带有 Amplify 的 react-admin。我的一种 graphql 类型有一个 AWSJSON 字段,其中包含一个 batchJob 的状态数组。我希望此数组显示在数据网格中,用户可以展开该数据网格以查看批次中每个项目的结果。
数据从 API 返回为字符串化 JSON。我如何才能 JSON.parse 将数据传递给 ArrayField 以在我的 list/show 组件中由 Datagrid 呈现?
该字段的内容如下所示:
[{"reference":"11134","status":"OK"},{"reference":"10278","status":"OK"}]
更新:下面的答案是在我将数据模型稍微更新为:
[{"id": "somerandomuid", "clientReference":"11134","status":"OK"}]
我的代码如下所示:
架构:
type JobTask
@model
@auth(
rules: [
{ allow: owner }
{ allow: groups, groups: ["admins"] }
]
) {
id: ID!
results: AWSJSON
status: String
expiryDate: AWSTimestamp! @ttl
}
显示组件:
export const TaskShow = (props) => {
return (
<Show title={props.header} {...props}>
<SimpleShowLayout>
<Datagrid expand={<ResultsPanel />}>
<TextField
key={cuid()}
fullWidth={true}
source="id"
label="Batch Id"
/>
<TextField
key={cuid()}
fullWidth={true}
source="status"
label="Status"
/>
</Datagrid>
</SimpleShowLayout>
</Show>
);
结果面板组件:
const ResultsPanel = (props) => {
console.log(props)
let resultsArray = JSON.parse(JSON.parse(props.record.results));
console.log(resultsArray);
return (
<>
{resultsArray.map((result) => {
return (
<ArrayField>
<Datagrid>
<TextField source="reference" />
<TextField source="status" />
</Datagrid>
</ArrayField>
);
})}
</>
);
};
但我得到的只是:
我想我会 post 将我的发现提供给可能正在为此苦苦挣扎的任何其他人。
Datagrid 需要上下文,列表组件将为它提供上下文,但由于这是在显示组件中,我试图使用数组来提供上下文。
ArrayField 组件需要一个 source prop,该 prop 必须是精确映射到 API 响应中的 field/property 的字符串;它 不能 是任意的 object/array。然而,字符串映射到的 属性 必须是一个数组,并且无法告诉组件在使用它之前处理 field/property 的内容。所以 Arrayfield 作为上下文提供者退出了。
由于 Array 不适用于我的数据结构,我想我可以使用 RA 的 listcontextprovider,它没有很好的文档记录,但似乎确实允许您构建可由数据网格使用的上下文,如据我所知。但是当我将它与正确的道具一起使用时,它总是给我一个错误(据我所知,无论如何 - 正如我所说,文档有点稀疏)。
最后,我放弃了原生 RA 组件,因为它不适合我的用例,而是编写了一个自定义字段组件来代替我需要的(即从记录中解析字段并将数组传递给要呈现的数据网格)。我使用了本机 MUI 数据网格,它非常有用:
const ResultsPanel = (props) => {
let resultsArray = JSON.parse(JSON.parse(props.record.results));
let columns = [
{ field: "id", headerName: "Item Id", flex: 1 },
{ field: "clientReference", headerName: "Your Reference", flex: 1 },
{ field: "status", headerName: "Import Status", flex: 1 },
];
return (
<div style={{ height: 400, width: "100%" }}>
<DataGrid columns={columns} rows={resultsArray} />
</div>
);
};