2

我有以下不可变列表的层次结构:

fromJS({
departments: [{
    departmentName: 'PHP',
    employees: [{
        employeeId: 1000,
        employeeName: 'Manish',
        projects: [{
            projectId: 200,
            projectName: 'ABC'
        },
        {
            projectId: 300,
            projectName: 'DEF'
        }]
    }]
}]
})

在此列表中,我想更新项目 ID 为200的项目名称。虽然我可以通过查找它们的索引来更新简单的一级对象数组,但我不知道如何在 immutableJS 中从这个开始。

4

3 回答 3

0

很久以前我有类似的东西......我使用了 flatMap 功能。最终我修改了我的状态结构,因为维护这段代码是一场噩梦。

updateProduct = (id, newName, data) => {
        return {
            departments: Immutable.flatMap(data.departments, (department => {
                return {
                    ...department,
                    employees: Immutable.flatMap(department.employees, (employee => {
                        return {
                            ...employee,
                            projects: Immutable.flatMap(employee.projects, (project => {
                                if (project.projectId == id) {
                                    return {
                                        ...project,
                                        projectName: newName
                                    }
                                }
                                else {
                                    return {...project}
                                }
                            }))
                        }
                    }))
                }
            }))
        }
    }
于 2018-08-28T20:38:40.073 回答
0

我相信使用 Immutable 执行此操作的惯用方法是使用大量的.map.update调用:

const state = fromJS(/*...*/);
const newState = state.update('departments',
  departments => departments.map(
    department => department.update('employees',
      employees => employees.map(
        employee => employee.update('projects',
          projects => projects.map(
            project => project.get('projectId') === 200 ?
            project.set('projectName', 'NEW_PROJECT_NAME') :
            project
          ))))));

const state = Immutable.fromJS({
  departments: [{
    departmentName: 'PHP',
    employees: [{
      employeeId: 1000,
      employeeName: 'Manish',
      projects: [{
          projectId: 200,
          projectName: 'ABC'
        },
        {
          projectId: 300,
          projectName: 'DEF'
        }
      ]
    }]
  }]
})

const newState = state.update('departments',
  departments => departments.map(
    department => department.update('employees',
      employees => employees.map(
        employee => employee.update('projects',
          projects => projects.map(
            project => project.get('projectId') === 200 ?
            project.set('projectName', 'NEW_PROJECT_NAME') :
            project
          ))))));

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

处理深度嵌套的数据很烦人。我认为如果你稍微扁平化你的数据结构,你可以让你的生活变得更简单。以这个结构为例:

const state = fromJS({
  departments: [{
    employeeIds: [ 1000 ]
  }],
  employees: {
    1000: {
      employeeId: 1000,
      employeeName: 'Manish',
      projectIds: [ 200, 300 ]
    }
  },
  projects: {
    200: {
      projectId: 200,
      projectName: 'ABC'
    },
    300: {
      projectId: 300,
      projectName: 'DEF'
    }
  }
});

使用这样的结构,您原始问题的答案将像单个一样简单updateIn

const newState = state.updateId(['projects', 200],
  project => project.set('projectName', 'NEW_PROJECT_NAME'));
于 2018-08-29T00:36:50.333 回答
0

我建议您不要将 immutable.js 用于此类复杂的数据结构,或者将结构重构为简单的集合。否则不仅你会遭受维护地狱的痛苦,而且性能会差数百倍(但你可能仍然没有注意到它,这取决于你的应用程序)。

于 2018-09-17T21:57:02.730 回答