Обновить родительский узел, если выбран дочерний узел - переход дерева от дочернего узла к родительскому - PullRequest
1 голос
/ 01 февраля 2020

Я хотел, чтобы все родители были выбраны, если выбран какой-либо из дочерних узлов. Поэтому, если какое-либо из дочерних узлов checked true, мне нужно установить родительское (до root) childSelected свойство, установленное в true

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

Ответы [ 2 ]

1 голос
/ 01 февраля 2020

Использовать рекурсию:

 function setSelected(node) {
   node.children.forEach(setSelected);

   node.childSelected = node.children.some(child => child.selected || child.childSelected);
 }
1 голос
/ 01 февраля 2020

Вам нужны две рекурсивные функции для оценки и установки значения. Вы также должны применить obj.children.length, чтобы избежать пометки себя как childrenChecked, если массив children пуст - ссылаясь на элемент 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));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...