如何更新不可变列表以获得新列表
How to update immutable List to get a new List
我有一个不可变的Map
,就像下面的
var mapA = Map({
listA: List.of({
id: 1,
name: 'Name A',
selected: false
}, {
id: 2,
name: 'Name B',
selected: false
})
});
我想更新列表中的密钥selected
。根据list.update
的immutable.js文档。
返回一个新列表,该列表在索引处具有更新的值调用更新程序的值
但是,如果我这样做
var listB = mapA.get('listA').update(1, function (item) {
item.selected = true;
return item;
});
并且,检查对象的相等性,它给了我true
。
console.log(listB === x.get('listA')); // true
我在这里做错了什么?immutable.js不就是这样工作的吗?
您还需要更新Map。
var mapB = mapA.update('listA', function(item) {
return item.update(1, function(item) {
item.selected = true;
return item;
});
});
问题是在不可变列表中使用了可变值。对于列表,对象不会更改,因为oldObject === newObject
仍然为true。
下面是一个简化的例子:
> var obj = {};
> var list = Immutable.List.of(obj);
> list2 = list.update(0, function(obj) { obj.foo = 42; return obj;});
> list2.get(0)
Object { foo: 42 }
> obj
Object { foo: 42 }
> list.get(0) === list2.get(0)
true
为了解决这个问题,除了更新地图(如果你想的话(,你还必须使用
- 更新时克隆对象
- 使用贴图而不是对象
- 在这种情况下可能最好:使用记录而不是对象
示例:
var MyRecord = new Immutable.Record({id: null, name: '', selected: false});
var mapA = Immutable.fromJS({
listA: [
new MyRecord({
id: 1,
name: 'Name A'
}),
new MyRecord({
id: 2,
name: 'Name B'
})
]
});
var mapB = mapA.updateIn(['listA', 1], function(record) {
return record.set('selected', true);
});
console.log(mapB.get('listA') === mapA.get('listA')); // false
以下是我的发现。问题是List
,它基本上是一个普通JavaScript对象的集合。它们是可变的。
解决方案很简单,我将最初的对象创建更改为这个。
var mapA = Immutable.fromJS({
listA: [{
id: 1,
name: 'Name A',
selected: false
}, {
id: 2,
name: 'Name B',
selected: false
}]
});
现在,以下工作如预期。
var mapB = mapA.setIn(['listA', 1, 'selected'], true);
相关文章:
- 使用下拉列表筛选列表(ul>li)
- 从要使用Protractor测试的服务器异步加载的动态数据列表的列表
- Knockout js 添加一个新列表
- 如何更改列表.js列表对象中的选项
- 如何避免/最小化列表中列表的缩进
- 如何对现有列表项使用CSS转换来为新列表项腾出空间
- 插入按字母顺序、javascript或jquery排序的新列表
- 链接下拉列表选择列表代码 -- 连接数据
- 停止对作为函数参数传递到新列表的对象引用
- 在 JavaScript 中创建具有重复列表条目的新列表的最快/推荐方法是什么
- 不是将新列表项推到底部,而是推到顶部
- 在 jQuery 中迭代数组时,每隔一个元素创建新列表
- 如何在JavaScript中重新加载页面以显示新列表
- Meteor-新列表项上的增量计数器:
- 如何将新列表项添加到无序列表中
- 如何更新不可变列表以获得新列表
- 单击list item将创建一个具有原始列表项'文本内容的新列表项
- reduce方法创建新列表,为什么未定义
- jQueryUI可排序连接列表-当项目滚动到新列表中时,未触发Over事件
- 如果是列表,则循环列表;如果是对象,则循环包含对象的新列表