Javascript 如果选择了子节点,则更新父节点-从子节点到父节点的树遍历
如果选择了任何一个子节点,我希望选择所有父节点。因此,如果任何childnodeJavascript 如果选择了子节点,则更新父节点-从子节点到父节点的树遍历,javascript,arrays,tree,treeview,Javascript,Arrays,Tree,Treeview,如果选择了任何一个子节点,我希望选择所有父节点。因此,如果任何childnode选中true,我需要将parent(直到root)childSelected属性设置为true var tree = [{ value: "A", checked: false, childSelected: false, children: [{ value: "AA", checked: false, childSelected: false, children:
选中
true,我需要将parent(直到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
}]
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
}]
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);
var树=[{
价值:“A”,
勾选:假,
所选儿童:假,
儿童:[{
值:“AA”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“A”
}, {
值:“AB”,
勾选:假,
所选儿童:假,
儿童:[{
值:“ABA”,
勾选:假,
所选儿童:假,
儿童:[{
值:“ABAA”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“ABA”
}, {
值:“ABAB”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“ABA”
}, {
值:“ABAC”,
核对:对,
所选儿童:假,
儿童:[],
家长:“ABA”
}, {
值:“ABAD”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“ABA”
}],
家长:“AB”
}],
家长:“A”
}, {
值:“AC”,
勾选:假,
所选儿童:假,
儿童:[{
价值:“ACA”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“AC”
}],
家长:“A”
}, {
价值:“广告”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“A”
}],
父项:null
}]
类复选框{
构造函数(){
this.checkboxTree=tree;
this.arrayPath=[];
}
setPartiallySelected(数据树){
dataTree.forEach((值、索引、arr)=>{
//控制台日志(arr,索引);
this.arrayPath.push(索引);
如果(!value.checked){
如果(value.children.length>0){
const childrenChecked=value.children.some(childValues=>{
if(childValues.checked){
返回true;
}
})
如果(!childrenChecked){
此.setPartiallySelected(value.children,value.parent)
}否则{
//更新父项
this.setSelectedPro(this.arrayPath,0,this.checkboxTree);
this.arrayPath.pop();
}
}否则{
this.arrayPath=[];
}
}否则{
}
if(arr.length-1==索引){
console.log(arr.length-1,索引)
this.arrayPath.pop();
}
})
}
setSelectedPro(父路径、当前索引、数据树){
console.log(“--------------”;
console.log(parentPath);
//log(parentPath、currentIndex、parentPath[currentIndex]);
log(dataTree[parentPath[currentIndex]];
currentIndex++;
if(currentIndex
您需要两个递归函数来计算和设置值。您还必须应用
obj.children.length
,以避免在childrenChecked
数组为空时将self标记为childrenChecked
-参考预期输出中的ABAC
元素)
var树=[{
价值:“A”,
勾选:假,
所选儿童:假,
儿童:[{
值:“AA”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“A”
}, {
值:“AB”,
勾选:假,
所选儿童:假,
儿童:[{
值:“ABA”,
勾选:假,
所选儿童:假,
儿童:[{
值:“ABAA”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“ABA”
}, {
值:“ABAB”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“ABA”
}, {
值:“ABAC”,
核对:对,
所选儿童:假,
儿童:[],
家长:“ABA”
}, {
值:“ABAD”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“ABA”
}],
家长:“AB”
}],
家长:“A”
}, {
值:“AC”,
勾选:假,
所选儿童:假,
儿童:[{
价值:“ACA”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“AC”
}],
家长:“A”
}, {
价值:“广告”,
勾选:假,
所选儿童:假,
儿童:[],
家长:“A”
}],
父项:null
}]
让isChecked=obj=>{
返回obj.checked | | obj.children.some(x=>isChecked(x));
};
让setChildSelected=obj=>{
让childSelected=obj.childrence.length>0&&isChecked(obj);
obj.children=obj.children.map(setChildSelected);
返回{…obj,childSelected};
};
log(tree.map(setChildSelected))代码>使用递归:
function setSelected(node) {
node.children.forEach(setSelected);
node.childSelected = node.children.some(child => child.selected || child.childSelected);
}
谢谢你这么好的回答。然而,我不明白发生了什么。你能补充一些例子吗?那太好了!什么样的例子?我建议您使用调试器并逐步完成代码。。。