如何使用 Normalizr 定义递归模型的模式
Posted
技术标签:
【中文标题】如何使用 Normalizr 定义递归模型的模式【英文标题】:How to define schema for recursive model with Normalizr 【发布时间】:2017-05-21 06:22:06 【问题描述】:在尝试规范化负载时遇到了一点问题,该负载包含与使用Normalizr的父级相同类型的嵌套架构
例如,我有一个初始对象 (menu
),它有一个子对象 (sections
),它是一个对象数组 (section
),可以深入。
id: 123,
sections: [
id: 1,
sections:[ id: 4, sections: [ id: 5, sections: [] ] ]
,
id: 2,
sections:[]
,
id: 3,
sections:[]
]
我首先创建了一个 menu
架构,它的定义中的部分链接到一个 sections
架构,适用于第一次传递,但随后无法处理部分的子节点,因此我添加了一个后续section
架构中具有相同名称的定义(值得一试),但它不起作用。
const section = new schema.Entity('sections')
const sections = new schema.Entity('sections',
sections: section
)
const menu = new schema.Entity('menu',
sections: [ sections ]
)
section.define( sections )
我希望最终得到以下对象:
entities:
menu:
sections: [1, 2, 3]
,
sections: [
1: id: 1, sections: [4] ,
2: id: 2, sections: [] ,
3: id: 3, sections: [] ,
4: id: 4, sections: [5] ,
5: id: 5, sections: [] ,
]
【问题讨论】:
那不行吗?这看起来比我用过的语法要新,但我不明白为什么它不起作用。 如果它确实有效,我不会向 SO 发布问题! :D 好点,可能是因为会话名称相同吗?您是否尝试过在形状中定义和使用自我。 【参考方案1】:如果有人有相同“类型”的嵌套对象的情况,例如“部分”,顶层结构也是“部分”的数组,如下所示:
const data = [
id: 1,
sections:[ id: 4, sections: [ id: 5, sections: [] ] ]
,
id: 2,
sections:[]
,
id: 3,
sections:[]
]
这里有一种“取消嵌套”它们的方法:
import schema, normalize from "normalizr";
const child = new schema.Entity("sections");
const sections = new schema.Array(child);
child.define(sections);
const topLevel = new schema.Entity("sections",
sections
);
const customSchema = [topLevel];
console.log(normalize(data, customSchema));
你会得到的是:
"entities":
"sections":
"1":
"id":1,
"sections":[
4
]
,
"2":
"id":2,
"sections":[
]
,
"3":
"id":3,
"sections":[
]
,
"4":
"id":4,
"sections":[
5
]
,
"5":
"id":5,
"sections":[
]
,
"result":[
1,
2,
3
]
【讨论】:
【参考方案2】:您的 sections
架构应该是 Array
。
const section = new schema.Entity('sections')
const sections = new schema.Array(section);
section.define( sections );
const menu = new schema.Entity('menu', sections );
那么,在使用中……
const data =
id: 123,
sections: [
id: 1,
sections:[ id: 4, sections: [ id: 5, sections: [] ] ]
,
id: 2,
sections:[]
,
id: 3,
sections:[]
]
;
normalize(data, menu)
将返回:
"entities":
"sections":
"1": "id": 1, "sections": [ 4 ] ,
"2": "id": 2, "sections": [] ,
"3": "id": 3, "sections": [] ,
"4": "id": 4, "sections": [ 5 ] ,
"5": "id": 5, "sections": []
,
"menu":
"123": "id": 123, "sections": [ 1, 2, 3 ]
,
"result": 123
【讨论】:
感谢 Paul,完全忽略了schema.Array
。很抱歉也发布了 Gitub 问题!感谢您的快速响应,周末愉快?
感谢您的这篇有用的帖子。如果***对象data
是一个部分数组,如何将该数组合并到相同的“entities.sections”对象中?在我的情况下不希望有menu
。
@EliBaird 检查我添加的答案,希望对您有所帮助。
很棒的例子!但是,我有一些自定义部分 id,我们称它们为 sectionId
而不仅仅是 id
。在schema.Entity()
上,可以使用ìdAttribute 添加option
参数来指定自定义ID,但在schema.Array
上似乎不可能,这会导致您的示例给出未定义的ID 值。有谁知道如何让您的递归数据示例与自定义 ID 一起使用?到目前为止,我已经通过sections.schema._idAttribute = "sectionId"
完成了它,但是以这种方式访问私有道具似乎有点不合时宜。以上是关于如何使用 Normalizr 定义递归模型的模式的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 normalizr 解析 FractalTransformer
如何使用 normalizr 规范化来自 JSON 的数据?
如何使用“normalizr”规范化这个简单的 API 响应?
如何添加/删除使用 normalizr 生成的 redux 存储?