如何使用normalizr分配与实体父实体相关的id/slug
示例:
用户调用的接口响应:
{
id: '12345',
firstName: 'John',
images: [
{
url: 'https://www.domain.com/image0',
name: 'image0'
},
{
url: 'https://www.domain.com/image1',
name: 'image1'
}
]
}我可以用以下方式定义我的模式:
const image = new Schema('images');
const user = new Schema('users');
user.define({
images: arrayOf(image)
})问题是图像没有id属性,所以除非我们提供id属性,否则normalizr将无法区分它们。当然,我们可以这样做
const image = new Schema('images', { idAttribute: uuid.v4() });并生成唯一标识符。
假设我们收到一个用户更新,并且图像的名称已经更新。因为我们在每次归一化中生成唯一的标识符,所以我们无法识别和更新现有图像。
我需要一种方法来引用图像实体中的父实体(用户)(在其id/slug中,如12345-image0、12345-image1或作为单独的属性。
实现这一目标的最佳方式是什么?
发布于 2017-02-23 05:34:41
idAttribute可以是一个函数,它接收引用状态切片的实体、父对象和键:
const image = new Schema('images', {
idAttribute: (entity, parent) => `${parent.id}-${entity.name}`
});发布于 2017-04-28 02:38:34
问题
以您显示的方式使用uuid将不起作用。
const image = new Schema('images', { idAttribute: uuid.v4() });uuid.v4()返回一个字符串,对于idAttribute来说,这是一个可接受的值,但是现在所有的images都将具有相同的uid。不是你想要的。
理想情况下,这是可行的:
const image = new Schema('images', { idAttribute: () => uuid.v4() });不幸的是,正如前面提到的in this issue,idAttribute将被多次调用。这将中断任何实体关系。在您的示例中,图像将具有与用户实体引用的uids不同的uids。
输出示例:
users: {
'12345': {
id: '12345',
firstName: 'John',
images: [
"cj20qq7zl00053j5ws9enz4w6",
"cj20q44vj00053j5wauawlr4u"
],
}
};
images: {
cj20q44v100003j5wglj6c5h8: {
url: 'https://www.example.org/image0',
name: 'image0'
},
cj20q44vg00013j5whajs12ed: {
url: 'https://www.example.org/image1',
name: 'image1'
}
};解决方案
解决这个问题的一种方法是改变processStrategy回调中的输入值,给它一个uid属性。
const getUid = value => {
if (!Object.prototype.hasOwnProperty.call(value, 'uid')) value.uid = uuid.v4();
return {...value};
};
const image = new Schema('images', { processStrategy: getUid, idAttribute: 'uid'});您现在正在改变值,所以这很糟糕,但是idAttribute选项使用输入值,而不是处理后的值。
或者,您可以更改idAttribute回调中的值,这样就不会将uid字段添加到输出值。
旁白:我推荐使用cuid npm包而不是uuid。
https://stackoverflow.com/questions/39681284
复制相似问题