Ext带复选框的Tree实现父子节点联动功能

来源:互联网 发布:上淘宝 编辑:程序博客网 时间:2024/05/18 07:59

昨晚有一个朋友问我EXT中带复选框的Tree控件是否可以实现节点被选中时父子节点联动的功能,之前做树形控件,一直都是在用Z-Tree的,速度快,功能强,这样的功能需求对于Z-Tree来说,完全小意思,原生API就可以支持的,偏偏到了EXT这里,就不行了。Ext本身是可以通过在节点属性中增加checked属性将一个普通节点变成带复选框的节点,但是奇怪的是,不支持父子节点联动功能,好怪异。

我觉得这个功能蛮简单的,刚好今天下午也有空,就自己写了一个demo,通过监听节点的checkchange事件来实现该功能,思路如下:

  1. 如果当前节点为父节点,则将当前节点的选中状态同步到所有的子节点;
  2. 如果当前节点被选中,则递归选中所有的祖先节点;
  3. 代码如下:
  4. Ext.require([    'Ext.tree.*',    'Ext.data.*',    'Ext.window.MessageBox']);Ext.onReady(function() {  //树数据存储器    var store = Ext.create('Ext.data.TreeStore', {        proxy: {      //通过ajax代理获取数据            type: 'ajax',            url: 'check-nodes.json'        },    //排序器,可以没有        sorters: [{            property: 'leaf',            direction: 'ASC'        }, {            property: 'text',            direction: 'ASC'        }]    });    var tree = Ext.create('Ext.tree.Panel', {    //指定数据源        store: store,    //是否显示根节点        rootVisible: false,    //是否箭头图标        useArrows: true,    //是否以框架显示        frame: true,    //标题        title: '多级节点联动树演示',    //树结构的容器ID        renderTo: 'tree-div',    //树面板宽度        width: 200,    //树面板高度        height: 250,    //事件监听器    listeners: {      //监听复选框的选中属性改变事件            checkchange : function(node,checked){        //获得父节点        pNode = node.parentNode;        //改变当前节点的选中状态        node.checked = checked;        //判断当前节点是否为叶子节点        var isLeaf = node.isLeaf();        //当该节点有子节点时,将所有子节点的选中状态同化        if (!isLeaf){          //cascade是指从当前节点node开始逐层下报,即遍历当前节点的每一个节点(无论有多少层级结构,详参API)          node.cascade(function(node){            node.set("checked", checked);          });        }        //如果当前节点是选中状态        if (checked == true) {          //将当前节点的所有未选中的父节点选中          for (;pNode != null && !pNode.get("checked");pNode = pNode.parentNode) {            pNode.set("checked", true);          }        }else{          //取消当前节点的所有不包含选中的子节点的父节点的选中状态          for (;pNode != null;pNode = pNode.parentNode) {            //如果当前的父节点包含选中的子节点,则终止搜索过程            if(hasCheckedNode(pNode)){              break;            }else{              //否则取消当前父节点的选中状态              pNode.set("checked", false);            }          }        }      }        }    });  //检查指定的父节点是否包含有选中的子节点  function hasCheckedNode(node){    var has = false;    //当前节点是否含有子节点    if(node.childNodes){      //遍历子节点      Ext.each(node.childNodes, function(item){        //如果当前节点是叶子节点        if(item.isLeaf()){          //遇到选中的子节点时终止搜索过程          if(has = item.get("checked")){            return false;          }        //遇到含有选中的子节点的父节点时终止搜索过程        }else if(has = hasCheckedNode(item)){          return false;        }      });    }    return has;  }});
0 0
原创粉丝点击