在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
虽然实现了类别多级的问题这样带来的后果确实无穷无尽的............. 递归查询,和双循环嵌套的执行sql语句没什么区别了...... 这样带来的是严重的性能问题.. 现在重新做这些东西,我想到了2个方案,第一个: 针对数据比较少的多级菜单,我们可以通过数据库一次查询出来所有记录,然后通过程序进行递归算法,进行数据的转化. 第二种: 就是数据库设计的时候,设计成多级别的菜单,每次加载通过ajax,一点一点展开(每一次展开都ajax请求下一级的数据),这样避免的递归带来的性能损失,而且实现简单方便,非常适合大数据量的时候,但是,一次只能显示一级,每次都要ajax请求下一级. 由于后台管理,第一次就按照第一种方案来设计: 首先,要设计好数据库,方便以后两种方式扩展, 这样设计,主要是考虑方便前台后台的扩展,FId字段是一个为了方便前台查询而设计的,这样设计的好处就是如果查询比如顶级菜单下的所有产品,只需要根据模糊查询前缀匹配,就能把所有的产品都查询出来,设计的字段还是有点小,IsLeaf是为了判断是否是叶子节点,BelongSid父级id, 前台代码: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>产品类别管理</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> <link href="../css/demo.css" rel="stylesheet" type="text/css" /> <script src="../scripts/jquery-1.6.2.min.js" type="text/javascript"></script> <script src="../scripts/miniui/miniui.js" type="text/javascript"></script><link href="../scripts/miniui/themes/default/miniui.css" rel="stylesheet" type="text/css" /> <link href="../scripts/miniui/themes/icons.css" rel="stylesheet" type="text/css" /> </head> <body> <div class="mini-toolbar"> <h1>产品类别管理</h1> <div class="mini-panel" title="产品类别管理" iconCls="icon-add" style="width:100%;height:500px;" showToolbar="true" showCollapseButton="true" showFooter="true" > <!--toolbar--> <div property="toolbar"> </div> <!--footer--> <div property="footer"> </div> <!--body--> <ul id="tree1" class="mini-tree" url="Data/GetProductInfo.ashx?method=GetProductType" style="width:100%;height:100%;padding:5px;" showTreeIcon="true" textField="text" idField="id" contextMenu="#treeMenu" > </ul> <ul id="treeMenu" class="mini-menu" style="display:none;" onbeforeopen="onBeforeOpen"> <!-- <li name="move" iconCls="icon-move" onclick="onMoveNode">移动节点</li>--> <li class="separator"></li> <li name="addNode" onclick="onAddNode" iconCls="icon-add">插入节点</li> <li name="edit" iconCls="icon-edit" onclick="onEditNode">编辑节点</li> <li name="remove" iconCls="icon-remove" onclick="onRemoveNode">删除节点</li> <li name="cancel" iconCls="icon-cancel" onclick="onCancel">取消</li> <li class="separator"></li> </ul> </div> <br /><br /> </div> <script type="text/javascript"> mini.parse(); var AddTpye="add"; function onCancel(e){ var tree=mini.get("tree1"); var node=tree.getSelectedNode(); tree.isExpandedNode (node); } function onAddBefore(e) { AddType="before"; AddItem(e); } function onAddAfter(e) { AddType="after"; AddItem(e); } function AddItem(e) { var tree = mini.get("tree1"); var node = tree.getSelectedNode(); var newNode = {id:0,text:"空",pid:node.id}; mini.prompt("请输入类别内容:", "请输入", function (action, value) { if (action == "ok"){ $.ajax({ url:"Data/GetProductInfo.ashx", type:"post", data:"method=AddProductType&text="+value+"&pid="+node.id+"&IsLeaf="+tree.isLeaf(node), success:function(msg){ if(msg){ alert("添加成功!"); TreeLoad(); // newNode.text=value; // if(node!=null){ // // tree.addNode(newNode, AddType, node); // } } else alert("添加失败!"); } }); } else { newNode.text="空"; } }); } //刷新树 function TreeLoad(){ $.ajax({ url:"Data/GetProductInfo.ashx?method=GetProductType", type:"json", success:function(json){ var tree = mini.get("tree1"); // alert(json); var data= eval("("+json+")"); tree.loadData(data); } }); } function onAddNode(e) { AddType="add"; AddItem(e); } function onEditNode(e) { var tree = mini.get("tree1"); var node = tree.getSelectedNode(); mini.prompt("请输入类别内容:", "请输入", function (action, value) { if (action == "ok") { $.ajax({ url:"Data/GetProductInfo.ashx", type:"post", data:"method=SaveProductType&id="+node.id+"&text="+value+"&pid="+node.pid+"&IsLeaf="+tree.isLeaf(node), success:function(msg){ if(msg){ alert("保存成功!"); tree.setNodeText(node,value); //TreeLoad(); } else alert("保存失败!"); } }); } }); } function onRemoveNode(e) { var tree = mini.get("tree1"); var node = tree.getSelectedNode(); if (node) { if (confirm("确定删除选中节点?")) { //这里提交到服务器 $.ajax({ url:"Data/GetProductInfo.ashx", type:"post", data:"method=RemoveProductType&id="+node.id, success:function(msg){ if(msg){ tree.removeNode(node); alert("删除成功!"); } else{ alert("删除失败!"); } } }); } } } function onBeforeOpen(e) { var menu = e.sender; var tree = mini.get("tree1"); var node = tree.getSelectedNode(); // if (node && node.id == "-1") { //如果根节点(总根目录,那么阻止菜单显示) // e.cancel = true; // //阻止浏览器默认右键菜单 // e.htmlEvent.preventDefault(); // return; // } //////////////////////////////// var editItem = mini.getbyName("edit", menu); var removeItem = mini.getbyName("remove", menu); var addNodeItem=mini.getbyName("addNode",menu); //var moveItem=mini.getbyName("move",menu); editItem.show(); removeItem.show(); addNodeItem.show(); if (node.id == "-1") {//总根目录 removeItem.hide(); // moveItem.hide(); } } </script> </body> </html> 这一个难点在于json数据递归生成: BLL中获得Tree的json数据 复制代码 代码如下: /// <summary> /// 工艺品类别树转化为json格式 /// </summary> /// <returns></returns> public string craftTypeTreeToJson() { //传递的json格式 IEnumerable<crafttype> craftTypeList = new crafttypeDAL().ListAll(); StringBuilder sb = new StringBuilder("["); foreach (crafttype root in craftTypeList) { if (root.Belongsid == -1) { sb.Append("{id:\"" + root.ID + "\",text:\"" + root.Name + "\""); sb.Append(",pid:\"-1\"");//添加父节点 sb.Append(",expanded:\"false\""); if (root.IsLeaf == "0")//如果是不是叶子节点,那么,就要递归添加children:[{xxx},内容 { sb.Append(",children:"); GetLeafTree(ref sb, (int)root.ID, craftTypeList);//递归追加叶子 } sb.Append("},"); } } sb.Remove(sb.Length - 1, 1); //去除掉最后一个多余的, sb.Append("]"); return Common.FormatToJson.MiniUiToJsonForTree(sb.ToString(), "工艺品类别"); } /// <summary> /// 递归获得父级ID下的所有类别json数据 /// </summary> /// <param name="sb">json字符串</param> /// <param name="parentID">父级id</param> /// <param name="craftTypeList">类别信息集合</param> public void GetLeafTree(ref StringBuilder sb,int parentID,IEnumerable<crafttype> craftTypeList) { sb.Append("["); foreach (crafttype leaf in craftTypeList) { if (leaf.Belongsid == parentID) //根据双亲节点查找叶子 { sb.Append("{id:\"" + leaf.ID + "\",text:\"" + leaf.Name + "\""); sb.Append(",pid:\"" + parentID + "\"");//添加父节点 sb.Append(",expanded:\"false\""); if (leaf.IsLeaf == "0")//如果是不是叶子节点,那么,就要递归添加children:[{xxx},内容 { sb.Append(",children:"); GetLeafTree(ref sb,(int)leaf.ID, craftTypeList);//递归追加叶子 } sb.Append("},"); } } sb.Remove(sb.Length - 1, 1); //去除掉最后一个多余的, sb.Append("]"); } 效果图如下: 虽然是ajax实现,不过这个确实ajax一次性把数据全部加载进去,这样对性能有严重的损失,不过考虑是后台,所以,没做处理,不过最好还是用第二种方法设计,那种方法是最好的解决方法,也适合前台的数据展示. 第二种方法正在实践中……… |
请发表评论