2016-05-13 40 views
0

推嵌套数据到一个地图列表里面不可变JS在列表更新地图

谁能告诉我:
我如何推任务到这些用户(列表项),理想的是由特定的用户ID?

在此先感谢。

我的代码:

const initialState = Immutable.List([ 
    Immutable.Map({ 
    "id": 1, 
    "name": "Abe Bell", 
    "tasks": [ 
     { 
     "id": 1, 
     "title": "Get haircut", 
     "status": false 
     } 
    ] 
    }), 
    Immutable.Map({ 
    "id": 2, 
    "name": "Chad Dim", 
    "tasks": [ 
     { 
     "id": 2, 
     "title": "Get real job", 
     "status": false 
     } 
    ] 
    }) 
]) 
+0

有没有一个很好的理由为什么你的状态是这样构建的?在我看来,你可以将其简化为仅使用地图。虽然完全有可能编辑当前结构,但这不必要的复杂。作为一个通用规则,为了性能/简单的原因,尽可能地选择在列表中映射。 – hazardous

回答

0

首先,你正在构建这种结构的方式,tasks阵列不会不可改变的情况下,我认为这是不是你想要的,你可以使用Immutable.fromJS改造什么所有的嵌套数组并映射到Immutable实例中。

您的数据结构的方式您必须浏览用户列表并在id匹配时执行更新。

这样做的一种方法是使用map

const initialState = Immutable.fromJS([ 
    { 
    "id": 1, 
    "name": "Abe Bell", 
    "tasks": [ 
     { 
     "id": 1, 
     "title": "Get haircut", 
     "status": false 
     } 
    ] 
    }, 
    { 
    "id": 2, 
    "name": "Chad Dim", 
    "tasks": [ 
     { 
     "id": 2, 
     "title": "Get real job", 
     "status": false 
     } 
    ] 
    } 
]); 

let userId = 2; 

let newState = initialState.map(user => { 
    if (user.get('id') !== userId) { 
    return user; 
    } 
    return user.update('tasks', tasks => {  
    return tasks.push(Immutable.fromJS({ 
     id: 3, 
     title: "new task", 
     status: false 
    })) 
    }); 
}); 

虽然这会做你想要什么,我想你应该你的数据更改为地图,而不是一个列表,如果这种操作的东西反复在你的申请。这将使事情变得更容易和更快。

const initialState = Immutable.fromJS({ 
    "1": { 
    "id": 1, 
    "name": "Abe Bell", 
    "tasks": [ 
     { 
     "id": 1, 
     "title": "Get haircut", 
     "status": false 
     } 
    ] 
    }, 
    "2": { 
    "id": 2, 
    "name": "Chad Dim", 
    "tasks": [ 
     { 
     "id": 2, 
     "title": "Get real job", 
     "status": false 
     } 
    ] 
    } 
}); 

let userId = "2"; 

let newState = initialState.updateIn([userId, 'tasks'], tasks => { 
    return tasks.push(Immutable.fromJS({ 
    id: 3, 
    title: "new task", 
    status: false 
    })); 
});