一直想弄个同步树,查阅相关资料开始动手写个,借鉴了相关资料,基本功能满足. 开始不知道这个Ext.tree.TreeCheckNodeUI 这个扩展的组件有什么作用,源码看不懂, 于是自己实现带有复选框的树以及父节点和子节点级联,就是在treepanel加个checkchange事件即可 listeners: { 'checkchange': function (node, checked) { if (node.parentNode && node.parentNode.getUI().checkbox != null) { checkParentFun(node.parentNode); } ChildTreeNodeFun(node, checked); } }, 具体实现用的是checkParentFun(node.parentNode),ChildTreeNodeFun(node, checked); 两个JS函数 Ext.tree.TreeCheckNodeUI 后来貌似懂了这个扩展的插件式干嘛的了,于是去除了监听事件, 不过感觉还是用这个扩展的插件和监听事件相结合使用才完美,具体的动手试试就知道了,粗略代码如下: 基本是通用的,尤其是对于权限管理中,角色和菜单之间的关联很实用 Ext.onReady(function() { Ext.QuickTips.init(); this.tree = new Ext.tree.TreePanel({ id:'tree', region: 'center', autoScroll: true, animate: true, width: '280', collapsible: (this.centerRegion=='center' ? false : true), split: true, tbar: [{xtype:"button",text:"logout",listeners:{ "click":function(){ssd(); }} }], enableDD: true, checkModel: 'cascade', //对树的级联多选 onlyLeafCheckable: false,//对树所有结点都可选 containerScroll: true, border: false, loader: new Ext.tree.TreeLoader({ url:'/neFunction/test', baseAttrs: { uiProvider: Ext.tree.TreeCheckNodeUI }//解决了获取树节点的级联多选问题 }), root: new Ext.tree.AsyncTreeNode({ id: "0", level: "0", text:"菜单树" }), // listeners: { // 'checkchange': function (node, checked) { // if (node.parentNode && node.parentNode.getUI().checkbox != null) { // checkParentFun(node.parentNode); // } // ChildTreeNodeFun(node, checked); // } // }, rootVisible: true }); this.tree.getRootNode().expand(); this.tree.addListener("click",this.ClickNode); this.contextMenu = new Ext.menu.Menu({ id:"treeContextMenu", items:[ { text:"查看", handler:function() { Ext.Msg.alert("...",Ext.getCmp('tree').getSelectionModel().getSelectedNode().id); } } ] }); this.tree.on("contextmenu",function(node,e) { e.preventDefault(); // 阻止弹出默认右键菜单 node.select(); // 选中节点 Ext.getCmp("treeContextMenu").showAt(e.getXY()); }); new Ext.Viewport({ renderTo:Ext.getBody(), layout : 'border', autoShow:true, items: [this.tree] }); }); function ClickNode(node){ console.info(node.attributes.id); } /** 父节点的选择 */ function checkParentFun (treeNode) { var i; var check = false; var nocheck = false; if (treeNode.hasChildNodes()) { for (i = 0; i < treeNode.childNodes.length; i++) { if (treeNode.childNodes[i].getUI().checkbox.checked) { check = true; } else { nocheck = true; } } } if (check == true && nocheck == false) { // 可以全选 treeNode.getUI().checkbox.checked = true; } else if (check == true && nocheck == true) { // 半选 孩子节点既有选中的也有未选中的 这种情况则父节点还是选中 treeNode.getUI().checkbox.checked = true; // treeNode.ui.toggleCheck(true); if(treeNode.parentNode&& treeNode.parentNode.getUI().checkbox != null){ checkParentFun(treeNode.parentNode); } } else if (check == false && nocheck == true) { // 全不选 孩子节点都是未选中的则父节点取消选中 treeNode.getUI().checkbox.checked = false; //treeNode.ui.toggleCheck(false); treeNode.collapse();//父节点收缩 if(treeNode.parentNode&& treeNode.parentNode.getUI().checkbox != null){ checkParentFun(treeNode.parentNode); } } }; /** 孩子节点的选择 */ function ChildTreeNodeFun (treeNode,checked) { var i; checked ? treeNode.expand() : treeNode.collapse();//点击某一节点让子节点都展开全部展开 if (treeNode.hasChildNodes()) { for (i = 0; i < treeNode.childNodes.length; i++) { if (treeNode.childNodes[i].getUI().checkbox) { treeNode.childNodes[i].getUI().checkbox.checked = checked; // treeNode.childNodes[i].ui.toggleCheck(checked); ChildTreeNodeFun(treeNode.childNodes[i],checked); } } } }; /** 根据路径对于节点的选择以及获取选中的节点 */ function ssd(){ tree.expandPath("/0/201/401/511");// var treeNode = Ext.getCmp("tree").getNodeById("511"); if (treeNode) { treeNode.getUI().checkbox.checked = true; } var checkedNodes = Ext.getCmp("tree").getChecked(); var s = []; for (var i = 0; i < checkedNodes.length; i++) { s.push(checkedNodes[i].text); } alert(s); }
后台代码 Tree这个类 对应extjs Ext.tree.TreeNode public class Tree implements Serializable { private static final long serialVersionUID = 1L; private String id; private String text; private String iconCls; private boolean expanded; private boolean leaf; private String url; private List<Tree> children; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getIconCls() { return iconCls; } public void setIconCls(String iconCls) { this.iconCls = iconCls; } public boolean isExpanded() { return expanded; } public void setExpanded(boolean expanded) { this.expanded = expanded; } public boolean isLeaf() { return leaf; } public void setLeaf(boolean leaf) { this.leaf = leaf; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public List<Tree> getChildren() { return children; } public void setChildren(List<Tree> children) { this.children = children; } }
package cn.com.starit.web.util; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import cn.com.starit.web.model.Menu; /*生成树JSON数组的类*/ public class TreeMenu { private List<Menu> list; private Menu root; public TreeMenu(List<Menu> list) { this.list = list; this.root = new Menu(); } /** * 组合json * * @param list * @param node */ private Tree getNodeJson(List<Menu> list, Menu node) { Tree tree = new Tree(); tree.setId("_authority_" + node.getId()); tree.setText(node.getName()); System.out.println(node.getName()); tree.setChildren(new ArrayList<Tree>()); if (list == null) { // 防止没有权限菜单时 return tree; } if (hasChild(list, node)) { List<Tree> lt = new ArrayList<Tree>(); tree.setLeaf(false); List<Menu> childList = getChildList(list, node); Iterator<Menu> it = childList.iterator(); while (it.hasNext()) { Menu modules = (Menu) it.next(); // 递归 lt.add(getNodeJson(list, modules)); } tree.setChildren(lt); } else { tree.setLeaf(true); } return tree; } /** * 判断是否有子节点 */ private boolean hasChild(List<Menu> list, Menu node) { return getChildList(list, node).size() > 0 ? true : false; } /** * 得到子节点列表 */ private List<Menu> getChildList(List<Menu> list, Menu modules) { List<Menu> li = new ArrayList<Menu>(); Iterator<Menu> it = list.iterator(); while (it.hasNext()) { Menu temp = (Menu) it.next(); if (temp.getParentId() == modules.getId()) { li.add(temp); } } return li; } public Tree getTreeJson() { // 父菜单的id为0 this.root.setId(0L); this.root.setName("根节点"); this.root.setIsLeaf("N"); return this.getNodeJson(this.list, this.root); } }
请求访问的controler层 @RequestMapping("/test") @ResponseBody public List<Tree> getTestInfoList() { List<Menu> list = testService.getMenuList(); //list为获取后台的菜单信息 TreeMenu menu = new TreeMenu(list); Tree tree = menu.getTreeJson(); return tree.getChildren(); } }