2016-09-24 24 views
10

如何使用normalizr來分配與實體父母相關的ID/slu??Normalizr - 如何生成與父實體相關的slu// ID

例子:

爲用戶呼叫

API響應:

{ 
    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屬性,所以normalizr將無法區分它們,除非我們提供id屬性。當然,我們可以做類似

const image = new Schema('images', { idAttribute: uuid.v4() }); 

並生成唯一的標識符。

假設我們收到用戶更新並更新了圖像的名稱。由於我們在每個規範化過程中生成唯一標識符,因此我們無法識別和更新現有圖像。

我需要的方式來引用在圖像實體的父實體(用戶)(或者在它的id /蛞蝓等12345-image012345-image1或作爲單獨的屬性。

什麼是實現這一目標的最佳方式?

回答

1

idAttribute可以是接收引用狀態的切片的實體,家長和鍵的功能:

const image = new Schema('images', { 
    idAttribute: (entity, parent) => `${parent.id}-${entity.name}` 
}); 
2

問題

使用uuid的方式顯示不起作用。

const image = new Schema('images', { idAttribute: uuid.v4() }); 

uuid.v4()返回一個字符串,idAttribute可接受的值,但現在所有的images都會有相同的UID。不是你想要的。

理想情況下這會工作:

const image = new Schema('images', { idAttribute:() => uuid.v4() }); 

不幸的是,idAttribute將被調用多次提到in this issue。這將打破任何實體關係。在您的示例中,圖像將具有與用戶實體引用它們不同的uid。

示例輸出:

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

+0

'processStrategy'沒有變異的價值,你可以返回一個新的對象與id字段。 – nathancahill

+0

'idAttribute'參數沒有引用返回的對象,它引用了原來的'value'。這就是爲什麼我必須改變原來的價值。 (除非我錯了,但我記得幾次檢查過,我也用保羅·阿姆斯特朗確認過) –

+1

你可能是對的,'getId'函數引用了原來的'input',而不是'processedEntity'在這裏:https: //github.com/paularmstrong/normalizr/blob/a20d535c0ddd21c95cf8498647fa8e060b5ed8a8/src/schemas/Entity.js#L61 – nathancahill