我如何使用normalizr来处理通过{ data: ... }
标准关键的嵌套标准化JSON API响应?
例如Book
{
data: {
title: 'Lord of the Rings',
pages: 9250,
publisher: {
data: {
name: 'HarperCollins LLC',
address: 'Big building next to the river',
city: 'Amsterdam'
},
},
author: {
data: {
name: 'J.R.R Tolkien',
country: 'UK',
age: 124,
}
}
}
}
如何设计模式来处理嵌套的数据键?
对于响应中的每个实体,应该创建它自己的模式。
在您的示例中,我们有三个实体- books
, authors
和publishers
:
// schemas.js
import { Schema } from 'normalizr';
const bookSchema = new Schema('book');
const publisherSchema = new Schema('publisher');
const authorSchema = new Schema('author');
如果某些实体包含需要规范化的嵌套数据,我们需要使用it模式的define
方法。此方法接受具有嵌套规则的对象。
如果我们需要规范化book
实体的publisher
和author
道具,我们应该传递一个与我们的响应结构相同的对象给define
函数:
// schemas.js
bookSchema.define({
data: {
publisher: publisherSchema,
author: authorSchema
}
});
现在我们可以标准化我们的响应:
import { normalize } from 'normalizr';
import { bookSchema } from './schemas.js';
const response = {
data: {
title: 'Lord of the Rings',
pages: 9250,
publisher: {
data: {
name: 'HarperCollins LLC',
address: 'Big building next to the river',
city: 'Amsterdam'
},
},
author: {
data: {
name: 'J.R.R Tolkien',
country: 'UK',
age: 124,
}
}
}
}
const data = normalize(response, bookSchema);
我相信你想要的是使用assignEntity
函数,它可以在normalize
的选项中传递。在本例中,它允许我们在适当的地方过滤掉多余的data
属性,并直接进入下面的值。
有效地assignEntity
让您控制如何规范化数据的每个键。请看这里了解更多关于它是如何工作的。
我把这些放在一起作为演示,看看:http://requirebin.com/?gist=b7d89679202a202d72c7eee24f5408b6。下面是一个片段:
book.define({
data: {
publisher: publisher,
author: author,
characters: normalizr.arrayOf(character)
}}
);
publisher.define({
data: {
country: country
}
});
const result = normalizr.normalize(response, book, { assignEntity: function (output, key, value, input) {
if (key === 'data') {
Object.keys(value).forEach(function(d){
output[d] = value[d];
})
} else {
output[key] = value;
}
}});
也可以特别看到Ln 29,其中characters
的数组中有一些对象的信息嵌套在data
中,而另一些则没有。
我还添加了一些部分来展示它如何处理数组和深度嵌套的数据,参见publisher
中的country
模型。
对于所提供的数据,由于没有id,您将需要一个分隔符,在示例中每个模式也包含id。
Normalizr是非常棒的,我希望这有助于更多地解释它:)