2016-06-12 44 views
0

我有趣的Immutable.js和有問題的合併對象與數組。Immutable.js mergeDeepWith問題

我對合並溫控功能是:

function singleTrackReducer(state = Immutable.Map(singleTrack), action) { 
    switch (action.type){ 
    case AudioFormActions.CHANGE: 
     return state.mergeDeepWith((prev, next) => next, action.entity); 
    default: 
     return state; 
    } 
} 

,我合併,看起來像這樣的對象:

const singleTrack = { 
    songTitle: '', 
    mainArtists: [], 
    featuredArtists: [], 
    releaseDate: '', 
    primaryGenre: '', 
    isExplicit: false, 
    labelName:'', 
    upCode: '', 
    eanCode: '', 
    isrcCode:'', 
    copyRight: '' 
}; 

我試圖更新mainArtists屬性。例如,我可以添加幾位藝術家加入我的藝術家陣列併成功執行更新。但是,當我從數組中刪除一個對象時,它似乎被一個前一個對象填充。

,比方說是藝術家的數組爲[公鴨,蕾哈娜,TYGA]

如果我呼籲用行動實體功能[公鴨,蕾哈娜,TYGA,約翰]它更新罰款和mainArtists財產變爲[公鴨,蕾哈娜,泰加,約翰]。

當我刪除一個藝術家例如TYGA和數組爲[公鴨,蕾哈娜,約翰]

的mainArtist財產變爲[公鴨,蕾哈娜,約翰,約翰]

誰能解釋我如何解決這個問題

回答

4

我覺得這個代碼將會幫助你理解這個問題:

var Immutable = require('immutable'); 

console.log(
    Immutable.List(['a', 'b', 'c']) 
    .mergeDeep(['a', 'c']) 
); 
// output: List [ "a", "c", "c" ] 

console.log(Immutable.List(['a', 'b', 'c']) 
    .mergeDeepWith((prev, next) => { 
    console.log(`Conflict between ${prev} and ${next}.`); 
    return next; 
    }, ['a', 'c']) 
); 
// output: Conflict between a and a. 
//   Conflict between b and c. 
//   List [ "a", "c", "c" ] 

基本上,合併列表時,項目會被複制FR如果在該索引處已經有一個值,則它被認爲是衝突:

  • 對於索引#0,第一個列表中有「a」,第二個列表中有「a」名單。我們通過優先選擇第二個值來解決衝突(儘管在這種情況下它們是相同的)。所以索引#0得到「a」。
  • 然後我們進入索引#1,找到第一個列表有「b」,第二個列表有「c」。我們通過選擇第二個值來解決衝突,所以索引#1得到「c」。
  • 現在索引#2,我們沒有衝突,因爲只有第一個列表有一個值。我們在索引#2中保留「c」,所以最終的列表是「a」,「c」,「c」。

你也可以使用一組,但基本上執行聯合操作,所以什麼都不會被刪除:

console.log(
    Immutable.Set(['a', 'b', 'c']) 
     .mergeDeep(['a', 'c']) 
); 
// output: Set { "a", "b", "c" } 

其實我不認爲你希望做的合併這個清單......我想你只是想將新價值複製到舊價值。如果是這種情況,也許你只是尋找merge而不是mergeDeep

var state = Immutable.Map({ 
    songTitle: '', 
    mainArtists: [], 
    featuredArtists: [], 
    releaseDate: '', 
    primaryGenre: '', 
    isExplicit: false, 
    labelName:'', 
    upCode: '', 
    eanCode: '', 
    isrcCode:'', 
    copyRight: '' 
}); 

function doMerge(state, newState) { 
    // no deep merge here, just copy whatever fields are present in newState 
    return state.merge(newState); 
} 

console.log(state.get('mainArtists')); 
// output: [] 

state = doMerge(state, { 
    mainArtists: ['drake', 'rihanna', 'tyga'] 
}); 
console.log(state.get('mainArtists')); 
// output: List [ "drake", "rihanna", "tyga" ] 

state = doMerge(state, { 
    mainArtists: ['drake', 'rihanna', 'tyga', 'john'] 
}); 
console.log(state.get('mainArtists')); 
// output: List [ "drake", "rihanna", "tyga", "john" ] 

state = doMerge(state, { 
    mainArtists: ['drake', 'rihanna', 'john'] 
}); 
console.log(state.get('mainArtists')); 
// output: List [ "drake", "rihanna", "john" ]