简体   繁体   English

ImmutableJS - 推入嵌套数组

[英]ImmutableJS - pushing into a nested array

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,console https://jsbin.com/midimupire/edit?html,js,console

Results in:结果是:

Error: invalid keyPath错误:无效的keyPath

I think that perhaps I need to set subList as a List() ;我想也许我需要将 subList 设置为List() I get the same error when trying this.尝试此操作时,我遇到了同样的错误。

If I understand the question correctly, you want to return collection with the first element as:如果我正确理解了这个问题,您希望将第一个元素的collection返回为:

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

To do this we'll need to make a few changes.为此,我们需要进行一些更改。

  1. Use Immutable.fromJS to deeply convert the plain JS array of objects to an Immutable List of Maps使用Immutable.fromJS将普通的 JS 对象数组深度转换为不可变的 Map 列表

  2. Use List.update() to return a new List with the updated value使用List.update()返回一个带有更新值的新List

  3. Use Map.updateIn() to return a new LMapist with the updated value使用Map.updateIn()返回具有更新值的新 LMapist

Here's the whole thing:这是整件事:

 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>

And the result:结果:

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

Update: List.updateIn() can use an index as the keypath, so you can simplify this to the following:更新: List.updateIn()可以使用索引作为键路径,因此您可以将其简化为以下内容:

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

Like this:像这样:

 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>

Use the object you got, update the subArray and return the whole object.使用你得到的对象,更新 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;
});

This doesn't work because the elements of your Immutable.List are plain-old JavaScript objects (POJO), not Immutable.Map s, so updateIn doesn't know how to work with them.这不起作用,因为您的Immutable.List的元素是普通的 JavaScript 对象 (POJO),而不是Immutable.Map s,所以updateIn不知道如何使用它们。 You can either:您可以:

  • Make the objects Immutable.Map s by using Immutable.fromJS instead of Immutable.List as the constructor to convert the entire object graph to Immutable objects.通过使用Immutable.fromJS而不是Immutable.List作为构造函数来使对象Immutable.Map s 将整个对象图转换为 Immutable 对象。 ( See JS Bin ) (见 JS Bin )
  • Use update([0]) instead of updateIn to just get the POJO and mutate it (as in @Navjot's answer).使用update([0])而不是updateIn来获取 POJO 并对其进行变异(如@Navjot 的回答)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM