https://zhuanlan.zhihu.com/p/55984381

许多API,都会返回一个深层的嵌套的对象。在js应用中使用这样的结构通常比较困难,尤其是用在flux以及redux中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"id": "123",
"author": {
"id": "1",
"name": "Paul"
},
"title": "My awesome blog post",
"comments": [
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
第一步,导包。
*/
import { normalize, schema } from 'normalizr';

/*
第四步,这一步其实没什么太多要说的了。user实际上已经被映射为一个object了。
那么,至此,三个被new schema.Entity 方法定义的变量将会被返回到最终的结果的entities上。
每个字符串作为顶层的 key 名。
*/
const user = new schema.Entity('users');

/*
第三步, 此时的comment已经被映射,那么同理,key: commenter的value: user 被映射为
{
"id": "2",
"name": "Nicole"
}。
第三步映射完毕。 我们继续网上看第四步。
*/
const comment = new schema.Entity('comments', {
commenter: user
});

/*
第二步, 为什么这里是第二步,而不是上面第二行代码(new schema.Entity('users');)?
因为,这里所返回的const article 将会直接传入到 normalize(originalData, article);
而与originalData第一次结合的schema才是第一步要分解的目标。
下一步,这里将会构建一个实体。注意,new schema.Entity的第一个入参可以随便写,
会体现在结果的entities['articles'].第二个入参,代表了originalData中含有嵌套的内容。
在这里,表示author会有嵌套,comments会有嵌套。
key: author,这个我就不说了,此 key 与 originalData 中的原名 key 一一对应,
然后此key的value,也就是 user 变量,映射为{ "id": "1", "name": "Paul" },(划重点)。
同理,key: comments 的value: [comment] 映射为
[
{
"id": "324",
"commenter": {
"id": "2",
"name": "Nicole"
}
}
]。
至此,user的变量映射完毕,comment变量映射完毕。
我们往上看第三步。
*/
const article = new schema.Entity('articles', {
author: user,
comments: [comment]
});

// 这一步,将原始数据结构 与 schema - article 结合在一起。返回最终结果。
const normalizedData = normalize(originalData, article);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
result: "123",
entities: {
"articles": {
"123": {
id: "123",
author: "1",
title: "My awesome blog post",
comments: [ "324" ]
}
},
"users": {
"1": { "id": "1", "name": "Paul" },
"2": { "id": "2", "name": "Nicole" }
},
"comments": {
"324": { id: "324", "commenter": "2" }
}
}
}