我同意你的看法。createEntityAdapter似乎进行了第一层规范化,因此输出";ids/实体";。我不确定将其与normalizer一起使用是否可行,因为createEntityAdapter的API公开了一些将数据放回其中的方法,如addONe或addMany,如果您将其与Normalizer一起用于规范化嵌套数据,我认为您不能将最外的方法(如addONe或addMany(用于使用库(normalizer(规范化的嵌套数据。
我正在尝试规范化以下结构Array<Application>
的数据数组。使用CCD_ 2。
在用createAsyncThunk
获取数据并返回后,我确实在extraReducers
中设置了它们,如下所示:
applicationsAdapter.setAll(state, action.payload)
在Redux DevTools中,我可以看到数据如下:
{
applications: {
ids: [
'60a684fb90957536f185ea88',
],
entities: {
'60a684fb90957536f185ea88': {
id: '60a684fb90957536f185ea88',
title: 'Article1',
description: 'The best article ever',
groups: [
{
id: 'bPDGd8uOkmKKAO3FyoTKE',
title: 'Group 1',
voters: [
{
user: {
uid: '344bc9b8-671b-4de5-ab2d-a619ea34d0ba',
username: 'tran',
},
vote: 'DECLINED'
}
]
}
],
deadline: "2021-05-20",
budget: 0,
createdAt: '2021-05-20',
createdBy: {
uid: 'ab2a8f19-c851-4a5f-9438-1000bfde205a',
username: 'admin',
},
},
}
问题:数据未完全规范化。如何规范组、投票者和用户对象?
以下是接口:
export interface Application {
id: string;
title: string;
description: string;
groups: Array<GroupElement>;
deadline: string;
budget?: number;
createdAt: string;
createdBy: User;
}
export interface GroupElement {
id: string;
title: string;
voters: Array<Voter>;
}
export interface User {
uid: string;
username: string;
}
export interface Voter {
user: User;
vote: Decision;
}
createEntityAdapter
本身不执行任何类型的关系规范化。为此,您需要使用normalizr
。
由于Voter
对象缺少自己的id属性,这是一个很难规范化的对象。我不得不拼凑一个。
import { schema, normalize } from "normalizr";
const user = new schema.Entity("user", {}, { idAttribute: "uid" });
const voter = new schema.Entity(
"voter",
{
user: user
},
{
idAttribute: (object) => `${object.vote}-${object.user.uid}`
}
);
const group = new schema.Entity("group", {
voters: [voter]
});
const application = new schema.Entity("application", {
createdBy: user,
groups: [group]
});
normalize(entity, application);
这将把你的数据转换为:
{
"entities": {
"user": {
"ab2a8f19-c851-4a5f-9438-1000bfde205a": {
"uid": "ab2a8f19-c851-4a5f-9438-1000bfde205a",
"username": "admin"
},
"344bc9b8-671b-4de5-ab2d-a619ea34d0ba": {
"uid": "344bc9b8-671b-4de5-ab2d-a619ea34d0ba",
"username": "tran"
}
},
"voter": {
"DECLINED-344bc9b8-671b-4de5-ab2d-a619ea34d0ba": {
"user": "344bc9b8-671b-4de5-ab2d-a619ea34d0ba",
"vote": "DECLINED"
}
},
"group": {
"bPDGd8uOkmKKAO3FyoTKE": {
"id": "bPDGd8uOkmKKAO3FyoTKE",
"title": "Group 1",
"voters": ["DECLINED-344bc9b8-671b-4de5-ab2d-a619ea34d0ba"]
}
},
"application": {
"60a684fb90957536f185ea88": {
"id": "60a684fb90957536f185ea88",
"title": "Article1",
"description": "The best article ever",
"groups": ["bPDGd8uOkmKKAO3FyoTKE"],
"deadline": "2021-05-20",
"budget": 0,
"createdAt": "2021-05-20",
"createdBy": "ab2a8f19-c851-4a5f-9438-1000bfde205a"
}
}
},
"result": "60a684fb90957536f185ea88"
}