如果所有子节点均被选中,如何将父树节点标记为已选中

时间:2019-10-09 07:49:02

标签: javascript tree

我有一个形成一棵树的json。

[{
    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,
        }
    ]
}]

现在我有一组选定的节点

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

markSelectedNodes方法可根据所选节点数组将节点标记为已选中

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);
        }
    });
}

现在,如果所有子节点都被标记为选中状态,则还应该将父节点标记为选中状态。

这可以通过堆栈实现吗?

1 个答案:

答案 0 :(得分:2)

您可以采用迭代和递归的方法,并检查是否选择了每个项目来更新父节点。

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; }

如果需要迭代所有嵌套数组,则可以存储标志,进行迭代并返回迭代结果。

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; }