如何在Immutable.js中按ID合并列表?

时间:2016-04-11 14:04:21

标签: javascript immutable.js

我有一个使用从服务器收到的JSON创建的不可变列表。我现在通过发送AJAX请求来更新其中一个人。来自服务器的响应返回更新的人员。如何使用更新的人更新不可变列表。我在下面的尝试只是通过索引替换list元素,这会产生不正确的结果。我想用人名替换它。

var Immutable = require('immutable');

// Get me all my people
var peopleResponse = [
    { username: 'jsmith', title: 'Manager',  dept: 'Engineering', salary: 100000 },
    { username: 'lwhite', title: 'Manager',  dept: 'Sales',       salary:  90000 }
];

// Convert to immutable structures
var people = Immutable.fromJS(peopleResponse);
console.log(people);

// Change lwhite's salary to 100,000
var updateResponse =
    { username: 'lwhite', title: 'Manager',  dept: 'Sales',       salary: 100000 }

var updatedPeople = [ Immutable.fromJS(updateResponse) ];

people = people.merge(updatedPeople);
console.log(people);

输出:

List [ Map { "username": "jsmith", "title": "Manager", "dept": "Engineering", "salary": 100000 }, Map { "username": "lwhite", "title": "Manager", "dept": "Sales", "salary": 90000 } ]
List [ Map { "username": "lwhite", "title": "Manager", "dept": "Sales", "salary": 100000 }, Map { "username": "lwhite", "title": "Manager", "dept": "Sales", "salary": 90000 } ]

请注意,更新后的列表有两个lwhite s!

1 个答案:

答案 0 :(得分:0)

我终于提出了以下解决方案。它的灵感来自normalizr。基本概念是人员列表只是一组用户名。实际的人物对象将位于由用户名键入的地图中。

var Immutable = require('immutable');

// Get me all my people
var peopleResponse = {
    result: ['jsmith', 'lwhite'],
    entities: {
        people: {
            jsmith: { username: 'jsmith', title: 'Manager',  dept: 'Engineering', salary: 100000 },
            lwhite: { username: 'lwhite', title: 'Manager',  dept: 'Sales',       salary:  90000 }
        }
    }
};

// Convert to immutable structures
var people = Immutable.fromJS(peopleResponse.result);
var peopleByUsername = Immutable.fromJS(peopleResponse.entities.people);
console.log(people);
console.log(peopleByUsername);

// Change lwhite's salary to 100,000
var updateResponse = {
    lwhite: { username: 'lwhite', title: 'Manager',  dept: 'Sales',       salary: 100000 }
};

var updatedPeopleByUsername = Immutable.fromJS(updateResponse);

peopleByUsername = peopleByUsername.merge(updatedPeopleByUsername);

console.log(people);
console.log(peopleByUsername);