很多导航菜单是树形的,即一级一级往下细分,这样的结构固然需要用递归来处理。 对于Freemarker 来说,宏就相当于函数,其定义了签名及参数列表。 所以在页面应这样写:
<ul> <!-- 递归 宏定义 --> <#macro bpTree children> <#if children?? && children?size gt 0> <#list children as child> <#if child.children?? && child.children?size gt 0> <li class="treeview"> <a href="javascript:void(0)"> <i class="${(child.mIcon=='')?string('fa fa-share',child.mIcon) }" aria-hidden="true"></i> <span>${child.mCname}</span> <i class="fa fa-angle-left pull-right" aria-hidden="true"></i> </a> <ul class="treeview-menu"> <@bpTree children=child.children /> </ul> </li> <#else> <li><a href="javascript:void(0)" onclick="loadContent('${child.mUrl}')"><i class="${ (child.mIcon=='')?string('fa fa-circle-o',child.mIcon) }" aria-hidden="true"></i> ${child.mCname}</a></li> </#if> </#list> </#if> </#macro> <!-- 调用宏 生成递归树 --> <@bpTree children=treeMenu /> </ul> 123456789101112131415161718192021222324 123456789101112131415161718192021222324treeMenu是Controller返回的JSON中的根元素,其值是JSONArray,所以最关键的核心问题是如何生成递归地数据结构。叶子节点的children为空数组。 Fremarker 宏 请参考博文:Freemarker定义宏的用法
后台Service查询数据库处理数据生成JSONArray的数据结构格式:
[ { "mCname": "框架应用管理", "mIcon": "fa fa-square-o", "mAppid": 1, "mIsclose": 0, "mIssys": 1, "mUrl": "", "children": [ { "mCname": "模块管理", "mIcon": "fa fa-cube", "mAppid": 1, "mIsclose": 0, "mIssys": 1, "mUrl": "AppMgr/ModuleManager/default.aspx", "children": [], "mOrderlevel": "0001", "mParentName": "框架应用管理", "mParentid": 1, "moduleid": 2, "mModulecode": "S00M00", "aAppName": "框架应用管理" }, { "mCname": "配置管理", "mIcon": "fa fa-cog", "mAppid": 1, "mIsclose": 0, "mIssys": 1, "mUrl": "AppMgr/ConfigManager/default.aspx", "children": [], "mOrderlevel": "0002", "mParentName": "框架应用管理", "mParentid": 1, "moduleid": 3, "mModulecode": "S00M01", "aAppName": "框架应用管理" }, { "mCname": "应用字段设置", "mIcon": "fa fa-key", "mAppid": 1, "mIsclose": 0, "mIssys": 1, "mUrl": "AppMgr/FieldManager/default.aspx", "children": [], "mOrderlevel": "0003", "mParentName": "框架应用管理", "mParentid": 1, "moduleid": 4, "mModulecode": "S00M02", "aAppName": "框架应用管理" }, { "mCname": "系统异常日志", "mIcon": "fa fa-file-pdf-o", "mAppid": 1, "mIsclose": 0, "mIssys": 1, "mUrl": "AppMgr/SystemErrorLog/default.aspx", "children": [], "mOrderlevel": "0004", "mParentName": "框架应用管理", "mParentid": 1, "moduleid": 5, "mModulecode": "S00M03", "aAppName": "框架应用管理" }, { "mCname": "事件日志", "mIcon": "fa fa-file-zip-o", "mAppid": 1, "mIsclose": 0, "mIssys": 1, "mUrl": "AppMgr/EventLog/default.aspx", "children": [], "mOrderlevel": "0005", "mParentName": "框架应用管理", "mParentid": 1, "moduleid": 6, "mModulecode": "S00M04", "aAppName": "框架应用管理" } ], "mOrderlevel": "0000", "mParentid": 0, "moduleid": 1, "mModulecode": "S00", "aAppName": "框架应用管理" }, { "mCname": "系统管理", "mIcon": "fa fa-cogs", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "", "children": [ { "mCname": "行政区管理", "mIcon": "fa fa-circle", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/AreaManager/default.aspx", "children": [], "mOrderlevel": "0001", "mParentName": "系统管理", "mParentid": 7, "moduleid": 8, "mModulecode": "S10M01", "aAppName": "应用系统管理" }, { "mCname": "组织机构管理", "mIcon": "fa fa-tree", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/CompanyManager/default.aspx", "children": [], "mOrderlevel": "0002", "mParentName": "系统管理", "mParentid": 7, "moduleid": 9, "mModulecode": "S10M02", "aAppName": "应用系统管理" }, { "mCname": "角色权限管理", "mIcon": "fa fa-user-secret", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/RoleManager/default.aspx", "children": [], "mOrderlevel": "0003", "mParentName": "系统管理", "mParentid": 7, "moduleid": 10, "mModulecode": "S10M03", "aAppName": "应用系统管理" }, { "mCname": "用户管理", "mIcon": "fa fa-users", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/UserManager/default.aspx", "children": [], "mOrderlevel": "0004", "mParentName": "系统管理", "mParentid": 7, "moduleid": 11, "mModulecode": "S10M04", "aAppName": "应用系统管理" }, { "mCname": "数据字典", "mIcon": "fa fa-leaf", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/FieldValueManager/default.aspx", "children": [], "mOrderlevel": "0005", "mParentName": "系统管理", "mParentid": 7, "moduleid": 12, "mModulecode": "S10M05", "aAppName": "应用系统管理" }, { "mCname": "在线用户列表", "mIcon": "fa fa-user", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/OnlineUser/default.aspx", "children": [], "mOrderlevel": "0009", "mParentName": "系统管理", "mParentid": 7, "moduleid": 16, "mModulecode": "S10M09", "aAppName": "应用系统管理" }, { "mCname": "系统设置", "mIcon": "fa fa-cog", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "", "children": [ { "mCname": "事件日志查询", "mIcon": "fa fa-search-minus", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/EventManager/default.aspx", "children": [], "mOrderlevel": "0006", "mParentName": "系统设置", "mParentid": 43, "moduleid": 13, "mModulecode": "S10M06", "aAppName": "应用系统管理" }, { "mCname": "系统参数管理", "mIcon": "fa fa-square", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/SystemParam/default.aspx", "children": [], "mOrderlevel": "0007", "mParentName": "系统设置", "mParentid": 43, "moduleid": 14, "mModulecode": "S10M07", "aAppName": "应用系统管理" }, { "mCname": "系统维护", "mIcon": "fa fa-shield", "mAppid": 2, "mIsclose": 0, "mIssys": 0, "mUrl": "SysMgr/SystemState/default.aspx", "children": [], "mOrderlevel": "0008", "mParentName": "系统设置", "mParentid": 43, "moduleid": 15, "mModulecode": "S10M08", "aAppName": "应用系统管理" } ], "mOrderlevel": "0010", "mParentName": "系统管理", "mParentid": 7, "moduleid": 43, "mModulecode": "S10M10", "aAppName": "应用系统管理" } ], "mOrderlevel": "0000", "mParentid": 0, "moduleid": 7, "mModulecode": "S10", "aAppName": "应用系统管理" }, { "mCname": "查询&报表统计", "mIcon": "", "mAppid": 3, "mIsclose": 0, "mIssys": 0, "mUrl": "", "children": [ { "mCname": "快递单查询", "mIcon": "", "mAppid": 3, "mIsclose": 0, "mIssys": 0, "mUrl": "ExpressMgr/ExpDocQuery/default.aspx", "children": [], "mOrderlevel": "0501", "mParentName": "查询&报表统计", "mParentid": 22, "moduleid": 35, "mModulecode": "S36M01", "aAppName": "物流快递管理系统" }, { "mCname": "快递营收统计", "mIcon": "", "mAppid": 3, "mIsclose": 0, "mIssys": 0, "mUrl": "ExpressMgr/ExpIncomeStat/default.aspx", "children": [], "mOrderlevel": "0502", "mParentName": "查询&报表统计", "mParentid": 22, "moduleid": 36, "mModulecode": "S36M02", "aAppName": "物流快递管理系统" }, { "mCname": "快递业务流量分析", "mIcon": "", "mAppid": 3, "mIsclose": 0, "mIssys": 0, "mUrl": "ExpressMgr/ExpDataAnalysis/default.aspx", "children": [], "mOrderlevel": "0503", "mParentName": "查询&报表统计", "mParentid": 22, "moduleid": 37, "mModulecode": "S36M03", "aAppName": "物流快递管理系统" }, { "mCname": "快递业务报表", "mIcon": "", "mAppid": 3, "mIsclose": 0, "mIssys": 0, "mUrl": "ExpressMgr/ExpCustomRpt/default.aspx", "children": [], "mOrderlevel": "0504", "mParentName": "查询&报表统计", "mParentid": 22, "moduleid": 38, "mModulecode": "S36M04", "aAppName": "物流快递管理系统" } ], "mOrderlevel": "0500", "mParentid": 0, "moduleid": 22, "mModulecode": "S36", "aAppName": "物流快递管理系统" } ] 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333要生成如上所示的JSONArray,其Service层也需要用递归来处理数据,Service层的写法,
// 返回json格式的树形导航菜单 public JSONArray getTreeMenu() { return treeMenuList(getModules(), 0); } // 菜单树形结构 public JSONArray treeMenuList(List<FrmModule> menuList, int parentId) { JSONArray childMenu = new JSONArray(); for (FrmModule menu : menuList) { if (parentId == menu.getmParentid()) { JSONObject jo = (JSONObject) JSONObject.toJSON(menu); JSONArray c_node = treeMenuList(menuList, menu.getModuleid()); jo.put("children", c_node); childMenu.add(jo); } } return childMenu; } 123456789101112131415161718 123456789101112131415161718然后在Controller层调用Service层生成的JSONArray,封装返回的JSON数据:
@RequestMapping(value = "/", method = RequestMethod.GET) public String home(Model model) { JSONArray ja = moduleService.getTreeMenu(); System.out.println(ja.toJSONString()); model.addAttribute("treeMenu",ja ); return "index"; } 1234567 1234567最后生成的树形菜单如下所示: