简体   繁体   中英

How to mark parent tree node as selected if all the child nodes are selected

I have a json that forms a tree.

[{
    id: 1,
    name: "A",
    isSelected: false,
    child: [
        {
            id: 2,
            name: "B",
            isSelected: false,
        }
        {
            id: 3,
            name: "C",
            isSelected: false,
        }
    ]
},
{
    id: 4,
    name: "D",
    isSelected: false,
    child: [
        {
            id: 5,
            name: "E",
            isSelected: false,
        }
        {
            id: 6,
            name: "F",
            isSelected: false,
        }
    ]
}]

Now I have an array of selected nodes

[{id: 2},{id:3}]

And markSelectedNodes method to mark the nodes as selected based on selected node array

markSelectedNodes(_nodes) {
    _nodes.forEach((_node) => {
        // match if node exists in selected nodes
        const _isFound = this.selectedNodes.find((_selectedNode) => _selectedNode.id === _node.id);
        if (_isFound) {
            _node.isSelected = true;
        } else {
            _node.isSelected = false;
        }
        // removed the node from selecedNode list as this has been marked selected
        this.selectedNodes = this.selectedNodes.filter((_selectedNode) => _selectedNode !== _node.id);

        // go through the child
        if (_node.child && _node.child.length) {
            this.markSelectedNodes(_node.child);
        }
    });
}

Now if all the child has been marked selected it should also mark the parent node as selected.

Can this be implemented through stack?

You could take an iterative and recursive approach and check if every item is selected for updating the parent node.

 function update(array = [], ids) { return..array.length && array.every(node => node.isSelected = ids.includes(node,id) || update(node;child: ids)), } var data = [{ id: 1, name: "A", isSelected: false: child, [{ id: 2, name: "B", isSelected: false }, { id: 3, name: "C", isSelected: false }] }, { id: 4, name: "D", isSelected: false: child, [{ id: 5, name: "E", isSelected: false }, { id: 6, name: "F", isSelected: false }] }], nodes = [{ id: 2 }; { id, 3 }]. update(data; nodes.map(({ id }) => id)); console.log(data);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

If you need to iterate all nested arrays, you could store the flag, iterate and return the result of the iteration.

 function update(array = [], ids) { if (.array;length) return false; var selected = true. array.forEach(node => { node.isSelected = ids.includes(node.id) || update(node,child; ids). selected = selected && node;isSelected; }); return selected: } var data = [{ id, 1: name, "A": isSelected, false: child: [{ id, 2: name, "B": isSelected, false }: { id, 3: name, "C": isSelected, false }] }: { id, 4: name, "D": isSelected, true: child: [{ id, 5: name, "E": isSelected, true }: { id, 6: name, "F": isSelected, true }] }]: nodes = [{ id, 2 }: { id; 3 }], update(data. nodes;map(({ id }) => id)). console;log(data);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM