2017-10-09 167 views
2
const List = Immutable.List; 
const items = [ 
    { id: 1, subList: [] }, 
    { id: 2, subList: [] }, 
    { id: 3, subList: [] } 
]; 
const newItem = { name: "sublist item" }; 

let collection = List(items); 

collection = collection.updateIn([0, 'subList'], function (items) { 
    return items.concat(newItem) 
}); 

https://jsbin.com/midimupire/edit?html,js,consoleImmutableJS - 推到嵌套陣列

結果:

Error: invalid keyPath

我想,也許我需要設置子列表作爲List();嘗試此操作時遇到同樣的錯誤。

+0

哪個鍵導致的錯誤? – Carcigenicate

+0

很難說(https://github.com/facebook/immutable-js/issues/635)。我知道從本地運行最新的Immutable,問題是[0]不能設置 – azz0r

+0

將'updateIn'更改爲'getIn',並嘗試刪除「subList」鍵。它是否返回第一張地圖? – Carcigenicate

回答

1

如果我理解正確的問題,要與第一個元素返回collection爲:

{ 
    id : 1, 
    subList: [ 
    {name: "sublist item"} 
    ] 
} 

要做到這一點,我們需要做一些修改。

  1. 使用Immutable.fromJS對象的純JS數組深深轉化爲地圖的不可變列表

  2. 使用List.update()與更新後的值

  3. 使用Map.updateIn()返回一個返回一個新的List具有更新值的新LMapist

H ERE是整個事情:

const List = Immutable.List; 
 
const items = [{ 
 
    id: 1, 
 
    subList: [] 
 
    }, 
 
    { 
 
    id: 2, 
 
    subList: [] 
 
    }, 
 
    { 
 
    id: 3, 
 
    subList: [] 
 
    } 
 
]; 
 
const newItem = { 
 
    name: "sublist item" 
 
}; 
 

 
let collection = Immutable.fromJS(items); 
 

 
collection = collection.update(0, item => { 
 
    return item.updateIn(['subList'], subList => { 
 
    return subList.concat(newItem); 
 
    }); 
 
}); 
 

 
console.log(collection)
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.js"></script>

而結果:

[ 
    { 
    "id": 1, 
    "subList": [ 
     { 
     "name": "sublist item" 
     } 
    ] 
    }, 
    { 
    "id": 2, 
    "subList": [] 
    }, 
    { 
    "id": 3, 
    "subList": [] 
    } 
] 

更新:List.updateIn()可以使用索引作爲的keyPath,這樣你就可以簡化這個以下:

collection = collection.updateIn([0, 'subList'], subList => { 
    return subList.concat(newItem); 
}); 

像這樣:

const List = Immutable.List; 
 
const items = [{ 
 
    id: 1, 
 
    subList: [] 
 
    }, 
 
    { 
 
    id: 2, 
 
    subList: [] 
 
    }, 
 
    { 
 
    id: 3, 
 
    subList: [] 
 
    } 
 
]; 
 
const newItem = { 
 
    name: "sublist item" 
 
}; 
 

 
let collection = Immutable.fromJS(items); 
 

 
collection = collection.updateIn([0, 'subList'], subList => { 
 
    return subList.concat(newItem); 
 
}); 
 

 
console.log(collection)
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.2/immutable.js"></script>

0

使用你得到的對象,更新subArray並返回整個對象。

const List = Immutable.List; 
const items = [ 
    { id: 1, subList: [] }, 
    { id: 2, subList: [] }, 
    {id: 3, subList: [] } 
]; 
const newItem = { name: "sublist item" }; 

let collection = List(items); 

collection = collection.update([0], function (obj) { 
    obj.subList = obj.subList.concat(newItem) 
    return obj; 
}); 
0

這不起作用,因爲你Immutable.List的元素是普通老式JavaScript對象(PO​​JO),不Immutable.Map S,所以updateIn不知道如何與他們合作。您可以:

  • 使用Immutable.fromJS代替Immutable.List作爲構造整個對象圖形轉換爲不可變對象使對象Immutable.Map秒。 (See JS Bin
  • 使用update([0])而不是updateIn來獲得POJO並對其進行變異(如@ Navjot的回答)。