问题
I have a deeply nested immutable structure with maps and lists. I'm not sure about the best way to update a nested map within the structure (the node with id:356).
I create a function to search the list, I find the target map, I update it. But the structure stays intact!! any idea what I'm doing wrong?
https://jsbin.com/sadoni/1/edit?js,console
var structure = Immutable.fromJS(
{
someKey:{id:1},
links:[
{id:123, c:false, chd:[]},
{id:134, c:false, chd:[
{id:212, c:false, chd:[
{id:245, c:false, chd:[]},
{id:256, c:false, chd:[]}
]},
{id:145, c:false, chd:[]},
{id:156, c:false, chd:[]},
{id:213, c:false, chd:[
{id:313, c:false, chd:[]},
{id:314, c:false, chd:[
{id:345, c:false, chd:[]},
{id:356, c:false, chd:[]}
]}
]}
]}
]
}
);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _findNode
function _findNode(nodes, func, cb){
let found = false;
var findInTree = (nodes, func) => {
if(nodes && nodes.size > 0){
nodes.forEach(node => {
if(found === false){
if (func(node) === true) {
found = true;
cb(node, nodes);
} else {
let chd = node.get('chd');
if(chd && chd.size > 0 && found === false){
findInTree(chd, func);
}
}
}
});
}
};
findInTree(nodes, func, cb);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _filter function
function filter(link){ return link.get('id')===356; }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _find the links array inside the tree
var links = structure.get('links');
function changeTheNode(node, nodes){
console.log(nodes.get(1).toJS()); // log nodes array before the update
var index = nodes.findIndex(function(n){ return n === node; });
nodes = nodes.update(index, function(itm){ return itm.set('c', true); });
// nodes array changed
console.log(nodes.get(1).toJS());
// structure tree is still the same :(
//console.log(structure.toJS());
}
_findNode(links, filter, changeTheNode);
回答1:
Recursion!
var data = Immutable.fromJS({
id:134, c:false, chd:[
{id:212, c:false, chd:[
{id:245, c:false, chd:[]},
{id:256, c:false, chd:[]}
]},
{id:145, c:false, chd:[]},
{id:156, c:false, chd:[]},
{id:213, c:false, chd:[
{id:313, c:false, chd:[]},
{id:314, c:false, chd:[
{id:345, c:false, chd:[]},
{id:356, c:false, chd:[]}
]}
]}
]
});
function search(val, target, changeTheNode) {
if (val.get('id') === target) {
return changeTheNode(val);
}
return val.set('chd',
val.get('chd')
.map((v) => search(v, target, changeTheNode))
);
}
var updatedData = search(data, 356, (node) => node.set('c', true))
The result is
{
"id": 134,
"c": false,
"chd": [
{
"id": 212,
"c": false,
"chd": [
{
"id": 245,
"c": false,
"chd": []
},
{
"id": 256,
"c": false,
"chd": []
}
]
},
{
"id": 145,
"c": false,
"chd": []
},
{
"id": 156,
"c": false,
"chd": []
},
{
"id": 213,
"c": false,
"chd": [
{
"id": 313,
"c": false,
"chd": []
},
{
"id": 314,
"c": false,
"chd": [
{
"id": 345,
"c": false,
"chd": []
},
{
"id": 356,
"c": true,
"chd": []
}
]
}
]
}
]
}
来源:https://stackoverflow.com/questions/34818901/immutable-js-structure-updating-nested-map