作者:林林7089 | 来源:互联网 | 2023-09-16 11:15
这里讨论的是含复选框的树中,当选中某节点时时,向上和向下的选中情况处理。下面为新建TreePanel实例。
情况一:当选中某节点时,展开并选中所有子孙节点;当取消选中某节点时,级联取消选中所有已加载子孙节点。复选框状态改变时都实现与上级节点关联。
var tree = new Ext.tree.TreePanel({id:'itree',loader: new Ext.tree.TreeLoader({dataUrl:'findTreeNode.action',baseParams:{}}),//是否显示线lines:true,autoScroll:true,root: new Ext.tree.AsyncTreeNode({text: '根节点',draggable: false,id: '0'}),//不显示根节点rootVisible:false,listeners:{'checkchange':function(node,checked){if(checked){//当选中当前节点时,展开并选中所有子孙节点expandInherit(node);}else{checkChilds(node);}checkParent(this,node);}}
})
情况二:
1、当前节点子孙节点已加载,若单击选中本节点,则级联选中其已加载子孙节点,展开本节点时再次确认将本节点选中状态应用于已加载子孙节点;若单击取消选中本节点,则级联取消选中所有已加载子孙节点,此时展开本节点不会影响子孙节点选中情况。
2、当前节点子节点未子节点加载,若单击选中本节点,则在首次展开加载节点数据后将当前节点选中状态应用于子节点;若当前节点未选中,展开不会影响子节点选中状态。
3、复选框状态改变时都实现与上级节点关联。
var tree = new Ext.tree.TreePanel({id:'itree',loader: new Ext.tree.TreeLoader({dataUrl:'findTreeNode.action',baseParams:{}}),//是否显示线lines:true,autoScroll:true,root: new Ext.tree.AsyncTreeNode({text: '根节点',draggable: false,id: '0'}),//不显示根节点rootVisible:false,listeners:{'checkchange':function(node,checked){if(node.loaded) checkChilds(node);//当本节点子节点已加载,则调用checkChilds方法checkParent(this,node);},//展开节点后触发'expandnode':function(node){/***功能:若展开节点为已选中,则将本节点选中状态应用于所有子孙节点*描述:实现处理选中节点未加载子孙节点,在首次展开加载子节点时对子节点选中状态进行处理*/if(node.attributes.checked){checkChilds(node);}}}
})
从上面TreePanel实例中可以看出,在选择某个节点复选框或展开某个节点时都有监听处理,其作用是同时向上和向下对节点进行选中状况处理。这里用到了四个递归的辅助方法,其代码如下:
//展开当前节点下所有子孙节点
expandChilds = function(node){if(node.isExpanded()){node.eachChild(function(child){expandChilds(child);});}else{var customfun = null;node.on("expand",customfun = function(){node.eachChild(function(child){expandChilds(child);});node.removeListener("expand",customfun,this);});node.expand();//展开当前节点子节点}
};//展开当前节点下所有子孙节点,并将当前节点选中状态应用于子孙节点
expandInherit = function(node){if(node.isExpanded()){//若该节点已展开,则将当前节点选中状态应用于该节点下所有子孙节点checkChilds(node);node.eachChild(function(child){expandInherit(child);});}else{var customfun = null;node.on("expand",customfun = function(){checkChilds(node);node.eachChild(function(child){expandChilds(child);});node.removeListener("expand",customfun,this);});node.expand();//展开当前节点子节点}
};//将当前节点的选中状态应用于向下的所有(已加载)子孙节点
checkChilds = function(node){var checked = node.attributes.checked;node.eachChild(function(child){child.attributes.checked = checked;child.ui.checkbox.checked = checked;checkChilds(child);});
};//选中当前节点时,对向上的父节点选中状态进行处理
checkParent = function(tree,node){var parentNode = node.parentNode;//由于根节点隐藏且没有复选框,所以当当前节点父节点为根节点时不再对父节点(根节点)进行选中状态处理if(tree.root.attributes.id != parentNode.attributes.id){//父节点中子节点选中个数计数var checkedCount = 0;//父节点中子节点数var childCount = parentNode.childNodes.length;parentNode.eachChild(function(child){if(child.attributes.checked){checkedCount++;}});if(checkedCount == childCount){//若父节点中子节点已被全选,则选中父节点parentNode.attributes.checked = true;parentNode.ui.checkbox.checked = true;}else{//若父节点中子节点未被全选,则将父节点置为不选中parentNode.attributes.checked = false;parentNode.ui.checkbox.checked = false;}checkParent(tree,parentNode);}
};
这样,当树中某节点被选中时,向上和向下的节点处理就完成了。
PS:以上不含半选的CheckBox树适用于初始化时不含选中节点的树,若用于含选中树时,需做适当修改。