zTree的联想[将数据表封装成自定义TreeNode,再将TreeNode生成json字串
2011-11-27 14:10
621 查看
由zTree的示范我们看到zTree支持多种数据类型,我认为json是最好的,项目中json肯定来自数据库,不可能就这样纯粹静态的,如何将数据库表中的属性信息生成json呢,这是关键问题,比如数据表读出的数据可能如下:
这里的SysFunction类封装的是系统功能表,这个类的定义如下:
每个功能可能有一个父功能,也可能没有,如下将他们封装成Json字串呢?
定义TreeNode类代表树形节点,注意观察这个类,关键代码都在里面实现了,比如如何让节点携带信息、如何将节点解析成JSON字串、如何向一个节点及子孙节点添加属性信息:
下面这个类是使用这个TreeNode生成需要的json字串,这个类解决了一个最关键的问题:就是将List集合封装成了一棵树TreeNode
下面是我的示范页面,如何使用这个类,注意观察id等于treeDemo3的代码:
运行结果:
//用一个集合模拟数据表的内容,也就是一下集合的内容完全可以查询自数据库 List<SysFunction> treeList = new ArrayList<SysFunction>(); treeList.add(new SysFunction("L01", null, "营销管理")); treeList.add(new SysFunction("L02",null,"客户管理")); treeList.add(new SysFunction("L03",null,"服务管理")); //营销管理的子功能 treeList.add(new SysFunction("L0101","L01","创建销售机会")); treeList.add(new SysFunction("L0102","L01","指派销售机会")); treeList.add(new SysFunction("L0103","L01","制定开发计划")); treeList.add(new SysFunction("L0104","L01","执行开发计划")); //指派销售机会的子功能 treeList.add(new SysFunction("L010201","L0102","经理指派")); treeList.add(new SysFunction("L010202","L0102","主管指派")); //客户管理的子功能 treeList.add(new SysFunction("L0201","L02","客户信息管理")); treeList.add(new SysFunction("L0202","L02","客户流失管理")); //服务管理子功能 treeList.add(new SysFunction("L0301","L03","咨询服务管理")); treeList.add(new SysFunction("L0302","L03","投诉服务管理")); treeList.add(new SysFunction("L0303","L03","查询服务管理"));
这里的SysFunction类封装的是系统功能表,这个类的定义如下:
/** * 系统功能对象 * */ class SysFunction { private String code; private String parentCode; private String title; /**功能编号*/ public String getCode() { return code; } public void setCode(String code) { this.code = code; } /**父级功能编号*/ public String getParentCode() { return parentCode; } public void setParentCode(String parentCode) { this.parentCode = parentCode; } /**功能名称,现在树上的节点文本*/ public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public SysFunction(String code, String parentCode, String title) { super(); this.code = code; this.parentCode = parentCode; this.title = title; } public SysFunction() { super(); } }
每个功能可能有一个父功能,也可能没有,如下将他们封装成Json字串呢?
定义TreeNode类代表树形节点,注意观察这个类,关键代码都在里面实现了,比如如何让节点携带信息、如何将节点解析成JSON字串、如何向一个节点及子孙节点添加属性信息:
/**自定义的树节点*/ class TreeNode { // 节点携带的值 private Map<String, Object> tag; // 儿子节点 private List<TreeNode> nodes; /**节点信息键值对,该属性不会为空指针,但可能没有键值对存在[就是map.size()==0]*/ public Map<String, Object> getTag() { if (tag == null) tag = new HashMap<String, Object>(); return tag; } public void setTag(Map<String, Object> tag) { this.tag = tag; } /**获得所有子节点,该属性不会为空指针,但可能没有集合元素存在*/ public List<TreeNode> getNodes() { if (nodes == null) nodes = new ArrayList<TreeNode>(); return nodes; } public void setNodes(List<TreeNode> nodes) { this.nodes = nodes; } public TreeNode(Map<String, Object> tag, List<TreeNode> nodes) { super(); this.tag = tag; this.nodes = nodes; } public TreeNode() { super(); } public TreeNode(Map<String, Object> tag) { super(); this.tag = tag; } /** * <pre> * 将当前TreeNode解析为JSON字串 构造的目标格式示例: * { * id:1, * name:'手机', * nodes:[ * {id:11,name:'诺基亚'}, * {id:12,name:'三星',nodes:[ * {id:121,name:'I9000(联通版)'}, * {id:122,name:'I9000(移动版)'}, * {id:123,name:'Galaxy Naos'} * ]}, * {id:13,name:'索爱'} * ] * } * </pre> * */ public String toJson(){ if (this.getNodes().size() == 0) throw new RuntimeException("节点不能没有任何属性"); return parseTreeNode(this); } @Override public String toString() { // TODO Auto-generated method stub return toJson(); } /** * <pre> * 将当前TreeNode解析为JSON字串 构造的目标格式示例: * { * id:1, * name:'手机', * nodes:[ * {id:11,name:'诺基亚'}, * {id:12,name:'三星',nodes:[ * {id:121,name:'I9000(联通版)'}, * {id:122,name:'I9000(移动版)'}, * {id:123,name:'Galaxy Naos'} * ]}, * {id:13,name:'索爱'} * ] * } * </pre> * */ private String parseTreeNode(TreeNode node) { if (node == null) throw new RuntimeException("节点不能为空"); StringBuilder nodeBuilder = new StringBuilder("{");// JSON对象开始 // 把Map中的键值对构造成json对象属性 for (Map.Entry<String, Object> kvp : node.getTag().entrySet()) { if (kvp.getValue().getClass() == String.class) nodeBuilder.append(kvp.getKey() + ":'" + kvp.getValue() + "',"); else nodeBuilder.append(kvp.getKey() + ":" + kvp.getValue() + ","); } // 构造子节点 nodeBuilder.append("nodes:["); // 子节点开始 for (TreeNode cnode : node.getNodes()) { if (cnode == null) continue; nodeBuilder.append(parseTreeNode(cnode) + ",");// 递归调用ParseTreeNode返回一个完整的JSON字串:"{属性1:value,属性2:value}" } if (nodeBuilder.charAt(nodeBuilder.length() - 1) == ',')// 去掉末尾逗号 nodeBuilder.deleteCharAt(nodeBuilder.length() - 1); nodeBuilder.append("]"); // 子节点结束 nodeBuilder.append("}"); // JSON对象结束 return nodeBuilder.toString(); } /** * 向指定节点及其子孙节点添加一个属性 * @author jiang * @param node 被放置属性的节点 * @param isrecursive 是否递归[当前节点的子孙节点]放置属性 * @param entries 放置的属性键值对 */ private void _putProperty(TreeNode node,Boolean isrecursive,Map.Entry<String,Object>...entries) { if (entries!=null) for (Map.Entry<String, Object> entry : entries) { node.getTag().put(entry.getKey(),entry.getValue()); } if (!isrecursive) return; for (TreeNode n : node.getNodes()) { _putProperty(n,isrecursive,entries); } } /** * 向指定节点及其子孙节点添加一个属性 * @author jiang * @param node 被放置属性的节点 * @param isrecursive 是否递归[当前节点的子孙节点]放置属性 * @param entries 放置的属性键值对 */ public void putProperty(Boolean isrecursive,Map.Entry<String,Object>...entries) { _putProperty(this,isrecursive,entries); } }
下面这个类是使用这个TreeNode生成需要的json字串,这个类解决了一个最关键的问题:就是将List集合封装成了一棵树TreeNode
public class TreeService {
public String getTree() {
//用一个集合模拟数据表的内容,也就是一下集合的内容完全可以查询自数据库 List<SysFunction> treeList = new ArrayList<SysFunction>(); treeList.add(new SysFunction("L01", null, "营销管理")); treeList.add(new SysFunction("L02",null,"客户管理")); treeList.add(new SysFunction("L03",null,"服务管理")); //营销管理的子功能 treeList.add(new SysFunction("L0101","L01","创建销售机会")); treeList.add(new SysFunction("L0102","L01","指派销售机会")); treeList.add(new SysFunction("L0103","L01","制定开发计划")); treeList.add(new SysFunction("L0104","L01","执行开发计划")); //指派销售机会的子功能 treeList.add(new SysFunction("L010201","L0102","经理指派")); treeList.add(new SysFunction("L010202","L0102","主管指派")); //客户管理的子功能 treeList.add(new SysFunction("L0201","L02","客户信息管理")); treeList.add(new SysFunction("L0202","L02","客户流失管理")); //服务管理子功能 treeList.add(new SysFunction("L0301","L03","咨询服务管理")); treeList.add(new SysFunction("L0302","L03","投诉服务管理")); treeList.add(new SysFunction("L0303","L03","查询服务管理"));
//将这个从集合封装成TreeNode
//构造一个根节点
TreeNode rootNode = new TreeNode();
rootNode.getTag().put("id", "L1");
rootNode.getTag().put("name", "CRM系统");
//将这个集合封装成Map
Map<String,TreeNode> treeNodeMap = new HashMap<String,TreeNode>();
//下面的循环完成两个功能:
// 1.将所有对象封装成Map里面的键值对,且值是TreeNode类型
// 2.将没有父节点的TreeNode添加到根节点rootNode
for(SysFunction sysFunction:treeList){
TreeNode node = new TreeNode();
node.getTag().put("id",sysFunction.getCode());
node.getTag().put("name", sysFunction.getTitle());
treeNodeMap.put(sysFunction.getCode(),node);
if (sysFunction.getParentCode()==null || "".equals(sysFunction.getParentCode())){//如果没有父节点则添加到根节点
rootNode.getNodes().add(node);
}
}
//下面的代码建立节点之间的从属关系
for(int i=0;i<treeList.size();i++){
SysFunction sysFunction = treeList.get(i);
if (treeNodeMap.containsKey(sysFunction.getParentCode())){//如果当前功能的父级功能编号在treeNodeMap中存在
treeNodeMap
.get(sysFunction.getParentCode())//找出父节点
.getNodes() //父节点的子节点集合
.add( //向子节点集合添加子节点
treeNodeMap.get(sysFunction.getCode())//找出子节点
);
}
}
//给根节点和它的子孙节点添加一个属性信息(open:true),展开节点
rootNode.putProperty(true, new SimpleEntry<String,Object>("open",true));
return rootNode.toJson();
}
}
下面是我的示范页面,如何使用这个类,注意观察id等于treeDemo3的代码:
<html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <link rel="stylesheet" href="demoStyle/demo.css" type="text/css"></link> <link rel="stylesheet" href="zTreeStyle/zTreeStyle.css" type="text/css"> <script type="text/javascript" src="jquery-1.4.2.js"></script> <script type="text/javascript" src="jquery.ztree-2.6.js"></script> <script type="text/javascript" src="asyncData/demoData.js"></script> <script type="text/javascript"> var setting1 = {showline:true,checkable:true}; //json var zTreeNodes1 = [ { "name":"google", "url":"http://g.cn", "target":"_blank"}, { "name":"baidu", "url":"http://baidu.com", "target":"_blank"}, { "name":"sina", "url":"http://www.sina.com.cn", "target":"_blank"} ]; var zTreeNodes2 = [ {id:1,name:'手机',nodes:[ {id:11,name:'诺基亚',nodes:[ {id:111,name:'C6(音乐版)'}, {id:112,name:'X6(导航版)'}, {id:113,name:'5230(世博版)'} ]}, {id:12,name:'三星'}, {id:13,name:'索爱'}, {id:14,name:'多普达'} ]}, {id:2,name:'电脑'}, {id:3,name:'家电'} ]; window.onload=function(){ $("#treeDemo1").zTree(setting1,zTreeNodes1); $("#treeDemo2").zTree({showline:true,checkable:false},zTreeNodes2); $("#treeDemo3").zTree({showline:true,checkable:true},[<%=new TreeService().getTree() %>]); }; </script> </head> <body> <div class="zTreeDemoBackground" style="float:left;"> <ul id="treeDemo1" class="tree" style="float:left;"></ul> </div> <div class="zTreeDemoBackground" style="float:left;"> <ul id="treeDemo2" class="tree"></ul> </div> <div class="zTreeDemoBackground" style="float:left;"> <ul id="treeDemo3" class="tree"></ul> </div> </body> </html>
运行结果:
相关文章推荐
- zTree联想终极篇-->将存储树形数据表封装成自定义TreeNode-->将自定义TreeNode解析成JSON树形字串
- C#将datatable生成easyui的绑定tree 的json数据格式
- node将目录下所有文件生成json数据,并批量重命名
- 利用TreeNode生成Json字符串
- 【COCOS2D-X(1.X 2.X) Json(cpp版)及新加字体库篇】在Cocos2dx引擎中封装、解析Json(cpp版)数据以及添加自定义字体库
- C#将datatable生成easyui的绑定tree 的json数据格式
- jQuery EasyUI:根据数据库内容生成适合于easyui-tree的JSON数据格式
- LigerUI中生成GRID与TREE的【JSON数据】与Asp.Net的【变量数据】(方便测试)
- asp.net数据库生成LigerUi树Tree结构Json格式数据(有点绕,附基本源代码)
- 封装JSON数据转自定义HTML方法parseHTML
- C#将datatable生成easyui的绑定tree 的json数据格式
- PHP生成tree需要的Json数据,数据来自于MySQL
- Java-封装生成JSON数据和XML数据类
- java根据数据库中的数据 的list 生成 tree 型 json
- JavaScript递归方法 生成 json tree 树形结构数据
- 捕获异常、存sd卡、自定义封装json(含网络工具类)、生成Json格式、传log日志到服务器、app崩溃友好重启
- C#将datatable生成easyui的绑定tree 的json数据格式
- C#将datatable生成easyui的绑定tree 的json数据格式
- 【COCOS2D-X(1.X 2.X) Json(cpp版)及新加字体库篇】在Cocos2dx引擎中封装、解析Json(cpp版)数据以及添加自定义字体库 .
- 学习笔记 Tianmao 篇 使用简单封装后的自定义OkHttp 获取json被GSON解析后的数据