extjs springMVC实现动态树形菜单
2014-11-08 22:28
477 查看
最近由于项目需要,做一个树形动态菜单,用extjs3 来做,结合springMVC,实现从后台动态的加载数据形成权限菜单。
表的设计如下:
使用pri_Id为外键,引用本表的主键,实现一张递归表。
这样springMVC就能以json的形式来返回权限菜单数据,前台的extjs就能解析到并加载。
实现的效果如下,当点击父菜单时,会将节点id传到后台再从后台加载数据回来。
注意从springMVC返回json数据时需要用到两个jar包:
jackson-core-asl-1.9.13.jar和jackson-mapper-asl-1.9.13.jar
一、数据表设计
首先是数据库的设计,数据库表是一张权限表(即菜单表),我把它设计成一张递归表,实现能显示父级菜单和子菜单的树形菜单,表的设计如下:
使用pri_Id为外键,引用本表的主键,实现一张递归表。
二、Java代码中po类的设计
po类的设计对应数据表中的数据(除了外键),用于做传送数据用。private Integer id;//节点id private String text;//节点名称 private boolean leaf;//是否为子节点 private String url;//节点点击的请求路径 private String cls;//节点的图标,folder还是file private Privilige parent;//父级菜单 private Set<Privilige> children = new HashSet<Privilige>();//子菜单 //getter...setter注意字段的名字不能变,因为返回json数据给前台时extjs会自动识别并加载。
三、前台extjs的jsp界面
Ext.QuickTips.init();//显示提示信息 //树加载器 var treeLoader = new Ext.tree.TreeLoader( { //获取数据库的远程地址 dataUrl:"${pageContext.request.contextPath }/Menu/showAllMenu" }); //当点击节点时传递节点id到服务器端上 treeLoader.on("beforeload",function(treeLoader,node){ this.baseParams.nodeId = node.id; }); //定义树 var tree = new Ext.tree.TreePanel({ id : 'tree', animate : true, autoScroll : true, containerScroll : true, lines : true, rootVisible:false,//不显示根节点 loader:treeLoader,//加载后台数据的树加载器 expanded:true, //根节点要用AsyncTreeNode root: new Ext.tree.AsyncTreeNode({ expanded: true, text:"系统菜单", id:"0", leaf:false }) });
四、设计privilige接口及实现类
public interface PrivilegeService { /** * 根据父级菜单的id获取其下的子菜单 */ List<Privilige> getMenuByParentId(Integer pid); /** * 判断用户是否拥有某项权限 * @param sysOper 登陆的操作员 * @param menuId 权限对应的id */ boolean hasPermission(Systemoper sysOper,Integer menuId); /** * 判断角色是否拥有某项权限 */ boolean hasPermission(Role role,Integer menuId); /** * 返回全部权限(菜单)数据给前台 * @param noteId * @return */ List<Privilige> getAllPriviliges(Integer noteId); }
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import net.seehope.dao.PriviligeDao; import net.seehope.po.Privilige; import net.seehope.po.Role; import net.seehope.po.Systemoper; import net.seehope.service.PrivilegeService; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional public class PrivilegeServiceImpl implements PrivilegeService { @Resource private SessionFactory sessionFactory; @Resource private PriviligeDao priviligeDao; public Session getSession(){ return sessionFactory.getCurrentSession(); } @SuppressWarnings("unchecked") @Override public List getAllPriviliges(Integer noteId) { List<Privilige> topList = (List<Privilige>) getSession() .createQuery("From Privilige p where p.parent IS NULL").list(); //存放返回的数据集 List<Map> list = new ArrayList<Map>(); Map map = null; if(noteId == 0){//首次加载树 //遍历所有的根节点 for (Privilige privilige : topList) { map = new HashMap(); map.put("id", privilige.getId()); map.put("text", privilige.getText()); map.put("leaf", privilige.isLeaf()); map.put("cls", privilige.getCls()); list.add(map); } }else{//非首次加载树 List<Privilige> leafMenu = getMenuByParentId(noteId);//根据父节点id获取其下子节点 Map m = null; //加载子节点 for (Privilige leafPri : leafMenu) { m = new HashMap(); m.put("id", leafPri.getId()); m.put("text", leafPri.getText()); m.put("leaf", leafPri.isLeaf()); m.put("cls", leafPri.getCls()); m.put("url", leafPri.getUrl()); list.add(m); } } return list; } @SuppressWarnings("unchecked") @Override public List<Privilige> getMenuByParentId(Integer pid) { String hql = "FROM Privilige p where p.parent.id = ?"; List<Privilige> list = getSession().createQuery(hql) .setParameter(0, pid).list(); return list; } @Override public boolean hasPermission(Systemoper sysOper, Integer menuId) { //拿到操作员的所有角色 for(Role role : sysOper.getSysrole()){ //拿到角色的所有权限 for(Privilige pri : role.getPriviliges()){ if(menuId.equals(pri.getId())){ return true; } } } return false; } @Override public boolean hasPermission(Role role, Integer menuId) { if(role.getPriviliges() != null && role.getPriviliges().size()>0){ for(Privilige pri : role.getPriviliges()){ if(menuId.equals(pri.getId())){ return true; } } } return false; } }
五、设计springMVC的控制类
import org.apache.log4j.Logger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import net.seehope.po.Privilige; import net.seehope.service.PrivilegeService; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * 操作权限的action * @author 毛健宇 * 创建日期: 2014-11-3 下午9:34:50 * @version 1.0.0 */ @Controller @RequestMapping("Menu") public class PrivilegeAction { /** * Logger for this class */ private static final Logger logger = Logger.getLogger(PrivilegeAction.class); @Resource private PrivilegeService privilegeServiceImpl; @RequestMapping(value="showAllMenu") public @ResponseBody List getTopPrivileges(HttpServletRequest request){ //获得父节点的id int nid = Integer.valueOf(request.getParameter("nodeId")); //获取所有权限 List<Privilige> Pris = privilegeServiceImpl.getAllPriviliges(nid); return Pris; } }
这样springMVC就能以json的形式来返回权限菜单数据,前台的extjs就能解析到并加载。
实现的效果如下,当点击父菜单时,会将节点id传到后台再从后台加载数据回来。
注意从springMVC返回json数据时需要用到两个jar包:
jackson-core-asl-1.9.13.jar和jackson-mapper-asl-1.9.13.jar
相关文章推荐
- JSP 实现动态树形菜单
- JAVASCRIPT + PHP 应用二:网页设计中树形菜单的动态实现
- Ztree树形菜单实现动态初始化、添加、删除、修改节点
- 动态实现树形菜单(使用dtree控件)
- dhtmlxTree+struts2实现简单的动态树形菜单
- JQuery实现动态生成树形菜单
- ExtJs Treepanel 实现整个树形菜单刷新
- dtree实现动态加载树形菜单,动态插入树形菜单
- JQuery实现动态生成树形菜单
- jQuery ztree实现动态树形多选菜单
- 如何实现动态树形菜单
- JavaScript + PHP 应用二:网页设计中树形菜单的动态实现
- Extjs动态树形菜单
- 动态树形菜单的实现
- javascript树形菜单(一):Tigra Tree Menu,实现动态数据加载
- 动态实现树形菜单
- dtree实现动态加载树形菜单,动态插入树形菜单
- C#——通过XML读取左侧菜单实现Extjs菜单动态加载
- 用MFC的消息映像实现动态菜单
- ASP + XML + JavaScript 实现动态无限级联动菜单