一、首先设计编写Menu实体类,存储每个菜单项的信息
package com.deppon.entity;
public class Menu {
private String tid;
private String text;
private boolean leaf;
private String parentId;
public String getTid() {
return tid;
}
public void setTid(String tid) {
this.tid = tid;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public boolean isLeaf() {
return leaf;
}
public void setLeaf(boolean leaf) {
this.leaf = leaf;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
@Override
public String toString() {
return "Menu [tid=" + tid + ", text=" + text + ", leaf=" + leaf
+ ", parentId=" + parentId + "]";
}
}
-
实体类有四个私有属性,tid是自身的id,
-
text就是菜单在页面显示的的数据,
-
leaf就是是否为叶子节点,
-
parentId为父亲节点的id
二、接下来设计数据库,插入数据(我用的是Oracle)
create table T_TREE
(
t_id VARCHAR2(10),
text NVARCHAR2(10),
leaf CHAR(1),
parent_id VARCHAR2(10)
)
- 需要注意的就是实体类是boolean值的leaf在数据库中用CHAR(1)存储,值为0或1
- 然后插入数据
insert into T_TREE values('101','一级菜单1',0,null);
insert into T_TREE values('102','一级菜单2',0,null);
insert into T_TREE values('103','一级菜单3',0,null);
insert into T_TREE values('1001','二级菜单1',1,'101');
insert into T_TREE values('1002','二级菜单2',0,'102');
insert into T_TREE values('1003','二级菜单3',0,'102');
insert into T_TREE values('1004','二级菜单4',0,'103');
insert into T_TREE values('1005','二级菜单5',0,'103');
insert into T_TREE values('10001','三级菜单1',1,'1002');
insert into T_TREE values('10002','三级菜单2',1,'1002');
insert into T_TREE values('10003','三级菜单3',1,'1003');
insert into T_TREE values('10004','三级菜单4',1,'1003');
insert into T_TREE values('10005','三级菜单5',1,'1004');
insert into T_TREE values('10006','三级菜单6',1,'1004');
insert into T_TREE values('10007','三级菜单7',1,'1004');
insert into T_TREE values('10008','三级菜单8',1,'1005');
insert into T_TREE values('10009','三级菜单9',1,'1005');
三、设计dao层,由于我是使用Mybatis的,就把mapper文件的代码粘贴一下
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="Menu"> <resultMap id="MenuResult" type="Menu"> <result property="tid" column="t_id" /> <result property="text" column="text" /> <result property="leaf" column="leaf" javaType="Boolean" jdbcType="CHAR"/> <result property="parentId" column="parent_id" /> </resultMap> <select id="findLeaf" parameterType="String" resultMap="MenuResult"> select t_id,text,leaf,parent_id from t_tree where 1=1 <choose> <when test="_parameter!=null and _parameter!=''"> and parent_id = #{_parameter} </when> <otherwise> and parent_id is null </otherwise> </choose> </select> </mapper>
- 主要的思路就是,根据父亲节点的id找到所对应的所有子节点
- 需要注意的是, <result property="leaf" column="leaf" javaType="Boolean" jdbcType="CHAR"/>这样的话,mybatis就会自动将数据库中的CHAR类型的leaf转化成布尔类型
下面是dao层的代码
package com.deppon.dao.impl; import java.util.List; import org.mybatis.spring.support.SqlSessionDaoSupport; import com.deppon.dao.IMenuDao; import com.deppon.entity.Menu; public class MenuDaoImpl extends SqlSessionDaoSupport implements IMenuDao{ @SuppressWarnings("unchecked") @Override public List<Menu> findLeaf(String tid) { return this.getSqlSession().selectList("Menu.findLeaf", tid); } }
IMenuDao是我写的一个dao接口,其实就是Service层调用Dao层接口,Action层再调用Service层接口
四、接下来编写界面js
Ext.onReady(function(){ var store = Ext.create('Ext.data.TreeStore', { autoLoad : true, proxy : { type : 'ajax', url : 'menuAction!findLeaf',//请求 reader : { type : 'json', root : 'menuList'//数据 }, //传参 extraParams : { tid : '' } }, root : { text : '管理菜单', expanded : true }, listeners : { 'beforeexpand' : function(node,eOpts){ //点击父亲节点的菜单会将节点的id通过ajax请求,将到后台 this.proxy.extraParams.tid = node.raw.tid; } } }); Ext.create('Ext.tree.Panel', { renderTo : Ext.getBody(), title : '动态加载TreePanel', width : 300, height : 500, useArrows : true, store : store }); });
首次加载的时候tid的值为空,所以就会从数据库把三个一级菜单查出来,
因为三个一级菜单的parent_id is null
五、最后编写Action
package com.deppon.action;
import java.util.List;
import com.deppon.entity.Menu;
import com.deppon.service.IMenuService;
public class MenuAction extends BaseAction {
private IMenuService menuService;
private String tid;
private List<Menu> menuList;
public String findLeaf() {
menuList = this.menuService.findLeaf(tid);
System.out.println(menuList);
return "findLeaf";
}
public void setMenuService(IMenuService menuService) {
this.menuService = menuService;
}
public String getTid() {
return tid;
}
public void setTid(String tid) {
this.tid = tid;
}
public List<Menu> getMenuList() {
return menuList;
}
public void setMenuList(List<Menu> menuList) {
this.menuList = menuList;
}
}
在struts.xml和application.xml配置Action
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <package name="default" namespace="/" extends="json-default"> <action name="menuAction" class="menuAction"> <result name="findLeaf" type="json"> <param name="includeProperties">menuList.*</param> </result> </action> </package> </struts>
<!-- 配置dao --> <bean id="menuDao" class="com.deppon.dao.impl.MenuDaoImpl" scope="prototype"> <property name="sqlSessionTemplate" ref="sqlSession"></property> </bean> <!-- 配置service --> <bean id="menuService" class="com.deppon.service.impl.MenuServiceImpl"> <property name="menuDao" ref="menuDao"></property> </bean> <!-- 配置Action --> <bean id="menuAction" class="com.deppon.action.MenuAction"> <property name="menuService" ref="menuService"></property> </bean>
这样基本上就写完了,现在我粘贴一下运行的效果
1、首次加载
2、全部展开
我是用ssm框架写的,可能有些同学没有用过,但是基本的思想,应该写的很清楚了