在做权限系统的时候,需要有一个树形的菜单。下图就是一个树形菜单的样式

但问题是,我们可以实现写死的树形菜单。什么是写死的?就是在前台代码中写好要加载的树形菜单是什么样子的。但是我们权限系统的要求是动态加载树形菜单,也就是根据数据库里面表的内容动态加载。

我首先要说的就是数据库设计,要想动态加载成树形菜单,数据库表中就一定要设置父节点ID和自身ID。通过父节点ID判断自身是属于哪一级菜单,而通过自身ID判断其对应的下一级菜单。这是数据库设计应该注意的地方,如果没有父节点和自身子节点,那么就没办法实现动态加载树形菜单。

动态加载树形菜单的实现利用的zTree。这里顺便提一下,zTree的网站做的真的很好,而且各种类型的zTree做的非常完美。我就是利用zTree来实现的,只不过与之不同的是zTree实现的树菜单也是在前台写好的,我们要做的就是将后台用数据库查询到的代码拼接成前台已经写好的代码格式。

这是前台写好的树菜单格式:

我们要做的就是将前台这种树形菜单格式在后台拼出来,而在树形菜单中显示的菜单名称是从数据库中查询出来的。最开始的时候尝试拼JSON串,但是事实证明,我失败了,拼出来的字符串运行的时候根本显示不出来

拼出的JSON串跟咱们要拼接的格式是不同的,JSON串拼接出来的格式适用于结构比较简单,这样利用循环可以将需要的字符串拼接出来。而我们需要的字符串是需要判断下一级是否有子节点的,这个利用JSON串我没有实现,只能实现一级菜单,而对应的实现三级菜单我没有拼出来。很遗憾,但是利用循环、遍历和DataTable的查询,最终实现了树形菜单字符串的拼接。下面是我实现的代码

这个对应的实现二级菜单的拼接

  1. public string getTree(string strTree)
  2. {
  3. string Chilstr = "";
  4. //获取DataTable
  5. zTreeBLL zTree = new zTreeBLL();
  6. DataTable dt = new DataTable();
  7. dt = zTree.QueryResource();
  8. //查询父节点有多少条不重复的数据
  9. zTreeBLL zTree1 = new zTreeBLL();
  10. DataTable dt1 = new DataTable();
  11. dt1 = zTree1.QueryParidNum();
  12. //父节点只能加到4
  13. //for (int p = 0; p < Convert.ToInt32(dt1.Rows[0][0]); p++)   //Convert.ToInt32强制转换字符,把Object类型转换成int
  14. //{
  15. int parentId = 0;
  16. //查找第一个父节点有多少个,即初值为0的父节点
  17. DataRow[] rowsP = dt.Select("ParentID=" + parentId);
  18. //利用循环将父节点拼接起来
  19. for (int i = 0; i < rowsP.Length; i++)
  20. {
  21. //把rowsP里面的数值取出来
  22. foreach (DataRow drP in rowsP)
  23. {
  24. string parName = drP["ResourceName"].ToString();
  25. //strTree = "[{name:\""+ parName + "\"";
  26. strTree = "[{name:\"" + parName + "\"";
  27. DataRow[] rowsC = dt.Select("ParentID=" + parentId + 1);
  28. if (rowsC.Length > 0)  //如果子节点不为0,则开始拼接子节点的字符串
  29. {
  30. //利用循环将父节点对应下的子节点串起来
  31. foreach (DataRow drC in rowsC)
  32. {
  33. string chilName = drC["ResourceName"].ToString();
  34. Chilstr = Chilstr + "{name:\"" + chilName + "\"}";
  35. Chilstr = Chilstr + ",";
  36. }
  37. Chilstr = Chilstr.Remove(Chilstr.LastIndexOf(","), 1);
  38. strTree = strTree + ",children:[" + Chilstr + "]}];";
  39. }
  40. else
  41. {
  42. strTree = strTree + "\"}];";
  43. }
  44. }
  45. }
  46. //    parentId++;
  47. //}
  48. return strTree;
  49. }

这个对应的是多级菜单的拼接

  1. public string getTree(string strTree)
  2. {
  3. string Chilstr = "";
  4. //获取DataTable
  5. zTreeBLL zTree = new zTreeBLL();
  6. DataTable dt = new DataTable();
  7. dt = zTree.QueryResource();
  8. //查询父节点有多少条不重复的数据
  9. zTreeBLL zTree1 = new zTreeBLL();
  10. DataTable dt1 = new DataTable();
  11. dt1 = zTree1.QueryParidNum();
  12. //父节点只能加到4
  13. //for (int p = 0; p < Convert.ToInt32(dt1.Rows[0][0]); p++)   //Convert.ToInt32强制转换字符,把Object类型转换成int
  14. //{
  15. int parentId = 0;
  16. //查找第一个父节点有多少个,即初值为0的父节点
  17. DataRow[] rowsP = dt.Select("ParentID=" + parentId);
  18. //利用循环将父节点拼接起来
  19. for (int i = 0; i < rowsP.Length; i++)
  20. {
  21. //把rowsP里面的数值取出来
  22. foreach (DataRow drP in rowsP)
  23. {
  24. string parName = drP["ResourceName"].ToString();
  25. //strTree = "[{name:\""+ parName + "\"";
  26. strTree = "[{name:\"" + parName + "\"";
  27. DataRow[] rowsC = dt.Select("ParentID=" + parentId + 1);
  28. if (rowsC.Length > 0)  //如果子节点不为0,则开始拼接子节点的字符串
  29. {
  30. //利用循环将父节点对应下的子节点串起来
  31. foreach (DataRow drC in rowsC)
  32. {
  33. string Threestr = "";
  34. //判断二级菜单下对应的ID,也就是查找三级菜单的ParentID
  35. string chilFollow = drC["ID"].ToString();
  36. //查询三级菜单
  37. DataRow[] rowsThree = dt.Select("ParentID=" + chilFollow);
  38. //判断是否存在三级菜单
  39. if (rowsThree.Length > 0)
  40. {
  41. foreach (DataRow drThree in rowsThree)
  42. {
  43. string ThreeName = drThree["ResourceName"].ToString();
  44. Threestr = Threestr + "{name:\""+ThreeName+"\"}";
  45. Threestr = Threestr + ",";
  46. }
  47. Threestr = Threestr.Remove(Threestr.LastIndexOf(","), 1);
  48. string chilName = drC["ResourceName"].ToString();
  49. Chilstr = Chilstr + "{name:\"" + chilName + "\",children:["+Threestr+"]},";
  50. }
  51. //如果不存在三级菜单的话直接加载二级菜单
  52. else
  53. {
  54. string chilName = drC["ResourceName"].ToString();
  55. Chilstr = Chilstr + "{name:\"" + chilName + "\"}";
  56. Chilstr = Chilstr + ",";
  57. }
  58. }
  59. Chilstr = Chilstr.Remove(Chilstr.LastIndexOf(","), 1);
  60. strTree = strTree + ",children:[" + Chilstr + "]}];";
  61. }
  62. else
  63. {
  64. strTree = strTree + "\"}];";
  65. }
  66. }
  67. }
  68. return strTree;
  69. }

最终实现的效果

其实实现这个例子的方法还有很多种,比如说递归。虽然JSON串没有拼接成功,但是我觉得JSON串是可以实现的。只是鉴于个人能力的缘故最终没有拼接成功。动态加载树形菜单终于实现的,但是还有很多需要改进的地方,比如如何将这个方法封装起来,以至于可以无限的调用没有缺陷等,这是下一步值得继续探讨的问题。

C#动态加载树菜单的更多相关文章

  1. ExtJS 创建动态加载树

    Ext 中导航树的创建有两种方式:1.首先将所有的数据读出来,然后绑定到前台页面.2.每点击一个节点展开后加载子节点.在数据量比较小的时候使用第一种方式加载的会快一些,然而当数据量比较大的时候,我还是 ...

  2. easyui_tree 复选框 动态加载树

    controller动态获取单位用户树 #region 下拉树菜单 /// <summary> /// 获取工作人员树菜单 /// </summary> /// <par ...

  3. dtree实现动态加载树形菜单,动态插入树形菜单

    1.导入  dtree文件    dtree.css   img文件夹   dtree.js 2. 建立对应 的数据库      1      父ID     name    id 3    建立连接 ...

  4. EasyUI Jquery 动态加载树,点击节点加载

    <script type="text/javascript"> $(function() { $(document).ready(function() { $.post ...

  5. jQuery 动态加载树

    本案例中用到了jquery的 tree插件,在本文的附件中可以下载 jsp代码: <%@ page language="java" import="java.uti ...

  6. Vue + Element UI 实现权限管理系统 前端篇(十):动态加载菜单

    动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...

  7. Vue + Element UI 实现权限管理系统(动态加载菜单)

    动态加载菜单 之前我们的导航树都是写死在页面里的,而实际应用中是需要从后台服务器获取菜单数据之后动态生成的. 我们在这里就用上一篇准备好的数据格式Mock出模拟数据,然后动态生成我们的导航菜单. 接口 ...

  8. C#遍历XML文件动态加载菜单

    通过遍历XML文件动态加载菜单,顺便利用WebBrowser控件实现一个简单的桌面浏览器 效果如下: 代码如下: XMLFile1.xml <?xml version="1.0&quo ...

  9. C#自定义控件、用户控件、动态加载菜单按钮

    一.效果图,动态加载5个菜单按钮: 二.实现方法 1.创建用户控件 2.在用户控件拖入toolStrip 3.进入用户控件的Lood事件,这里自动添加5个选  ToolStripMenuItem,后期 ...

随机推荐

  1. java利用jxl操作Excel

    /** * 把从数据库查询到的数据,写入电子表格 * * @throws Exception */ public void createXls() throws Exception { Dao dao ...

  2. Elasticsearch refresh vs. flush【转载】

    源地址:    http://www.jianshu.com/p/0e9f6346f1fe 问: 若一个新的文档索引进ES索引,则它在索引操作执行后约1s可以搜索到.然而我们可以直接调用_flush或 ...

  3. node.js 基础学习笔记3 -http

    http模块,其中封装了一个高效的HTTP服务器和一个建议的HTTP客户端 http.server是一个基于事件的HTTP服务器 http.request则是一个HTTP客户端工具,用户向服务器发送请 ...

  4. 图解Android Studio导入Eclipse项目源码

    方法/步骤   打开Android Studio,在主页面中选择"File"->"New"->"Import project...&quo ...

  5. Web服务器Nginx多方位优化策略

    标签:性能 Web 架构 Nginx 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://dongsong.blog.51cto.co ...

  6. redis 内存泄露

    http://www.oschina.net/question/2266476_246221 http://stackoverflow.com/questions/24304212/how-to-de ...

  7. 遇到的check the manual that corresponds to your MySQL server version for the right syntax错误

    遇到的check the manual that corresponds to your MySQL server version for the right syntax错误. 结果发现是SQL关键 ...

  8. redis pipeline

    redis pipeline 简而言之就是把多个redis命令打包,一起发送给redis server,并且一起返回结果,减少客户端和服务器之间的多次“折返跑”

  9. unreal3脚本stacktrace的问题

    在unrealscript里获取调用栈,有下面两函数: /** * Dumps the current script function stack to the log file, useful * ...

  10. 网站加载css/js/img等静态文件失败

    网站加载css/js/img等静态文件失败,报网站http服务器内部500错误.而服务器中静态文件存在且权限正常. 从浏览器中直接访问文件,出来乱码.这种问题原因在于iis中该网站mime配置报错,不 ...