【问题标题】:Update parent node if child node is selected - Tree traverse from child node to parent如果选择子节点,则更新父节点 - 从子节点到父节点的树遍历
【发布时间】:2020-02-01 19:46:58
【问题描述】:

如果选择了任何一个子节点,我想让所有父节点都被选中。所以如果任何一个子节点checked为真,我需要将父节点(直到根)childSelected属性设置为真

var tree = [{
  value: "A",
  checked: false,
  childSelected: false,
  children: [{
    value: "AA",
    checked: false,
    childSelected: false,
    children: [],
    parent: "A"
  }, {
    value: "AB",
    checked: false,
    childSelected: false,
    children: [{
      value: "ABA",
      checked: false,
      childSelected: false,
      children: [{
        value: "ABAA",
        checked: false,
        childSelected: false,
        children: [],
        parent: "ABA"
      }, {
        value: "ABAB",
        checked: false,
        childSelected: false,
        children: [],
        parent: "ABA"
      }, {
        value: "ABAC",
        checked: true,
        childSelected: false,
        children: [],
        parent: "ABA"
      }, {
        value: "ABAD",
        checked: false,
        childSelected: false,
        children: [],
        parent: "ABA"
      }],
      parent: "AB"
    }],
    parent: "A"
  }, {
    value: "AC",
    checked: false,
    childSelected: false,
    children: [{
    value: "ACA",
    checked: false,
    childSelected: false,
    children: [],
    parent: "AC"
  }],
    parent: "A"
  }, {
    value: "AD",
    checked: false,
    childSelected: false,
    children: [],
    parent: "A"
  }],
  parent: null
}]

预期输出

var tree = [{
  value: "A",
  checked: false,
  childSelected: true,
  children: [{
    value: "AA",
    checked: false,
    childSelected: false,
    children: [],
    parent: "A"
  }, {
    value: "AB",
    checked: false,
    childSelected: true,
    children: [{
      value: "ABA",
      checked: false,
      childSelected: false,
      children: [{
        value: "ABAA",
        checked: false,
        childSelected: false,
        children: [],
        parent: "ABA"
      }, {
        value: "ABAB",
        checked: false,
        childSelected: false,
        children: [],
        parent: "ABA"
      }, {
        value: "ABAC",
        checked: true,
        childSelected: false,
        children: [],
        parent: "ABA"
      }, {
        value: "ABAD",
        checked: false,
        childSelected: false,
        children: [],
        parent: "ABA"
      }],
      parent: "AB"
    }],
    parent: "A"
  }, {
    value: "AC",
    checked: false,
    childSelected: false,
    children: [{
    value: "ACA",
    checked: false,
    childSelected: false,
    children: [],
    parent: "AC"
  }],
    parent: "A"
  }, {
    value: "AD",
    checked: false,
    childSelected: false,
    children: [],
    parent: "A"
  }],
  parent: null
}]

这是我迄今为止尝试过的

var tree = [{
      value: "A",
      checked: false,
      childSelected: false,
      children: [{
        value: "AA",
        checked: false,
        childSelected: false,
        children: [],
        parent: "A"
      }, {
        value: "AB",
        checked: false,
        childSelected: false,
        children: [{
          value: "ABA",
          checked: false,
          childSelected: false,
          children: [{
            value: "ABAA",
            checked: false,
            childSelected: false,
            children: [],
            parent: "ABA"
          }, {
            value: "ABAB",
            checked: false,
            childSelected: false,
            children: [],
            parent: "ABA"
          }, {
            value: "ABAC",
            checked: true,
            childSelected: false,
            children: [],
            parent: "ABA"
          }, {
            value: "ABAD",
            checked: false,
            childSelected: false,
            children: [],
            parent: "ABA"
          }],
          parent: "AB"
        }],
        parent: "A"
      }, {
        value: "AC",
        checked: false,
        childSelected: false,
        children: [{
        value: "ACA",
        checked: false,
        childSelected: false,
        children: [],
        parent: "AC"
      }],
        parent: "A"
      }, {
        value: "AD",
        checked: false,
        childSelected: false,
        children: [],
        parent: "A"
      }],
      parent: null
    }]

class checkbox{
    constructor() {
        this.checkboxTree = tree;
    this.arrayPath = [];
  }

  setPartiallySelected(dataTree) {
    dataTree.forEach((value, index, arr) => {
      // console.log(arr, index);
      this.arrayPath.push(index);
        if(!value.checked) {
            if(value.children.length > 0) {
                const childrenChecked = value.children.some(childValues => {
                    if(childValues.checked) {
                        return true;
                    }
                }) 
                if(!childrenChecked) {
                  this.setPartiallySelected(value.children, value.parent)
                } else {
                    // update parent
                    this.setSelectedPro(this.arrayPath, 0, this.checkboxTree);
                    this.arrayPath.pop();
                }
            } else {
              this.arrayPath = [];
            }
        } else {

        }
        if(arr.length - 1 === index) {
          console.log(arr.length - 1, index)
          this.arrayPath.pop();
        }

    })
  }

  setSelectedPro(parentPath, currentIndex, dataTree) {
    console.log("--------------");
    console.log(parentPath);
    // console.log(parentPath, currentIndex, parentPath[currentIndex]);
    console.log(dataTree[parentPath[currentIndex]]); 
    currentIndex++;
    if(currentIndex < parentPath.length ) {
      dataTree[parentPath[currentIndex - 1]].isPartiallyChecked = true;
      this.setSelectedPro(parentPath, currentIndex, dataTree[parentPath[currentIndex - 1]].children);
    }       
  }
}

var obj = new checkbox();
obj.setPartiallySelected(tree);

JsFiddle

【问题讨论】:

    标签: javascript arrays tree treeview


    【解决方案1】:

    使用递归:

     function setSelected(node) {
       node.children.forEach(setSelected);
    
       node.childSelected = node.children.some(child => child.selected || child.childSelected);
     }
    

    【讨论】:

    • 感谢您的出色回答。但是,我无法理解发生了什么。你能补充一些例子吗?真的很棒!
    • 什么样的例子?我建议使用您的调试器并单步执行代码...
    【解决方案2】:

    您需要两个递归函数来评估和设置值。如果children 数组为空,您还必须应用obj.children.length 以避免将self 标记为childrenChecked - 指的是预期输出中的ABAC 元素)

    let isChecked = obj => {
        return obj.checked || obj.children.some(x => isChecked(x));
    };
    
    let setChildSelected = obj => {
        let childSelected = obj.children.length > 0 && isChecked(obj);
        obj.children = obj.children.map(setChildSelected);
        return { ...obj, childSelected };
    };
    
    console.log(tree.map(setChildSelected));
    

    var tree = [{
      value: "A",
      checked: false,
      childSelected: false,
      children: [{
        value: "AA",
        checked: false,
        childSelected: false,
        children: [],
        parent: "A"
      }, {
        value: "AB",
        checked: false,
        childSelected: false,
        children: [{
          value: "ABA",
          checked: false,
          childSelected: false,
          children: [{
            value: "ABAA",
            checked: false,
            childSelected: false,
            children: [],
            parent: "ABA"
          }, {
            value: "ABAB",
            checked: false,
            childSelected: false,
            children: [],
            parent: "ABA"
          }, {
            value: "ABAC",
            checked: true,
            childSelected: false,
            children: [],
            parent: "ABA"
          }, {
            value: "ABAD",
            checked: false,
            childSelected: false,
            children: [],
            parent: "ABA"
          }],
          parent: "AB"
        }],
        parent: "A"
      }, {
        value: "AC",
        checked: false,
        childSelected: false,
        children: [{
        value: "ACA",
        checked: false,
        childSelected: false,
        children: [],
        parent: "AC"
      }],
        parent: "A"
      }, {
        value: "AD",
        checked: false,
        childSelected: false,
        children: [],
        parent: "A"
      }],
      parent: null
    }]
    
    let isChecked = obj => {
        return obj.checked || obj.children.some(x => isChecked(x)); 
    };
    
    let setChildSelected = obj => {
        let childSelected = obj.children.length > 0 && isChecked(obj);
        obj.children = obj.children.map(setChildSelected);
        return { ...obj, childSelected };
    };
    
    console.log(tree.map(setChildSelected));

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-20
      • 1970-01-01
      相关资源
      最近更新 更多