2017-10-09 135 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的回答)。