【发布时间】:2016-12-23 09:22:42
【问题描述】:
我有一个这样的树结构数据:
[{
id: 54,
name:123,
children: [{
id: 54,
name:123,
children: [{
id: 154,
name:1234,
children []...
}]
}]
}, {
...
}]
我正在使用 Angular 2。据我所知,只要输入发生更改,更改检测就会启动,而您的更改检测策略是 onPush。
为了优化树结构更新(例如在嵌套级别切换节点或更改此类节点的任何属性),我使用了Immutable。
不可变如何帮助我优化更新?我读到不可变会在数据发生变化时重用旧数据中的引用来构造新对象。
如何有效地使用不可变数据结构来更新嵌套级别的节点?
假设
- 我没有任何节点的
keyPath。 - 每个节点都有一个唯一的
id属性值,可用于查询树数据(但如何?)
问题
- 如何在嵌套级别的某处更新节点?联系该节点的最有效方式是什么?
- 如何更新多个节点?我听说过
withMutationsAPI,但是还有其他有效的方法吗?
我的方法
-
深拷贝一切,然后修改新构造的对象:
var newState = deepClone(oldState) // deep copy everything and construct a new object newState.nodes.forEach(node => { if(node.id == 54) { node.id = 789; } }) -
我正在尝试实现的内容:
var newState = Immutable.fromJS(oldState) // create an immutable object newState = newState.find(node => { node.set("id", 123); }); // any changes to object will return new object
我希望通过第二种方案实现节点的复用,如下图:
【问题讨论】:
-
“不可变更新”是矛盾的。你有一个价值,你想要另一个相似的价值,所以你创造差异并分享相似之处
-
@Caleth 同意了。但是需要您的帮助来有效地找到一种方法来到达树中的节点并更新它
-
您创建了一个新树。您引用它们而不是复制未更改的值,这是安全的,因为 没有任何变化
-
那么您的数据结构是打算更新(可变)还是打算将更改应用于您制作的副本(不可变)整体复制?后者当然效率较低。
-
“如果我让树数据不可变并且只更新其中的一部分”:这是不可能。根据“不可变”的定义,不可变树不能更新它的任何部分。您只是在寻找更新树。
标签: javascript immutability immutable.js immutable-collections