后台系统的权限管理中,总是会用到资源,而前台展示的时候,EXTjs 中很多时候会用树形去展示资源。
这里我以项目中角色中管理资源为例。(用的是Spring3.1.2管理项目MVC)
(1)首先看一下前台的角色中的js代码:
{ fieldLabel : '资源模块', height: 300, xtype : 'treepanel', width: 280, checkModel: 'cascade', region : 'east', onlyLeafCheckable: false,//对树所有结点都可选 animate: false, rootVisible: false, autoScroll:true, root: { nodeType: 'async' }, loader: new Ext.tree.TreeLoader({ dataUrl: 'system/resource/resourceTree.json?type=2', baseAttrs: {uiProvider: Ext.ux.TreeCheckNodeUI} }), listeners: { checkchange: function(node, checked){ node.expand(); node.attributes.checked = checked; node.eachChild(function(child) { child.ui.toggleCheck(checked); child.attributes.checked = checked; child.fireEvent('checkchange', child, checked); }) }, afterRender: function (t) { treeP = t; treeP.root.expand(true); } } }这是extjs中的代码,具体的属性,我就不详细解释了,看文档。
(2)根据dataUrl: 'system/resource/resourceTree.json?type=2'
请求的路径,我们在后台的控制类中Controller中:
/** * 资源树 * @param model */ @RequestMapping("resourceTree") public void resourceTree(Model model,Integer type) { List<TreeNode> listChildNode =resourceService.getChildNodeList(0,type==1?false:true); List<TreeNode> listNode = new ArrayList<TreeNode>(); TreeNode node =new TreeNode(); node.setText("平台后台"); node.setLeaf(false); node.setType(0); node.setId(0); if(type==2){ node.setChecked(false); } node.setChildren(listChildNode); listNode.add(node); model.addAttribute("nodes",listNode); model.addAttribute(SUCCESS, true); }(3)在逻辑处理层Service中:
/** * 树形集合 * @param pid * @return */ public List<TreeNode> getChildNodeList(int pid,boolean hasChecked){ List<TreeNode> list =resourceMapper.selectChildNodeList(pid); for(TreeNode rn:list){ List<TreeNode> innerList =getChildNodeList(rn.getId(),hasChecked); rn.setChildren(innerList); if(hasChecked){ rn.setChecked(false); }; if(rn.getPid().intValue()==0){ rn.setLeaf(false);//第一级全部不是叶子 }else{ rn.setLeaf(innerList.size()==0?true:false); } } return list; }这里用到了一个递归的函数方法调用,目的是遍历所有的根的节点
(4)在映射类Mapper中代码:
/** * 找出子节点 * @param pid * @return */ List<TreeNode> selectChildNodeList(int pid);
(5)在XMl配置中的SQl语句:
<select id="selectChildNodeList" resultType="TreeNode" parameterType="Integer"> SELECT id,name,pid,display_name as text,type,create_time as createTime,sort FROM sb_resource WHERE pid=#{pid} </select>(6)这样得到的前台的展示:
这样就大体的介绍了用spring的MVC管理项目,数据用EXTjs展示的树形的流程。
(7)另外再介绍一下,怎样用树形展示角色拥有的资源.
(8)同样在js中代码:
{ fieldLabel : '资源模块', height: 300, xtype : 'treepanel', width: 280, checkModel: 'cascade', region : 'east', onlyLeafCheckable: false,//对树所有结点都可选 animate: false, rootVisible: false, autoScroll:true, root: { nodeType: 'async' }, loader: new Ext.tree.TreeLoader({ dataUrl: 'system/resource/getResourceByRole.json?roleId='+record.get('id'), baseAttrs: {uiProvider: Ext.ux.TreeCheckNodeUI} }), listeners: { checkchange: function(node, checked){ node.expand(); node.attributes.checked = checked; node.eachChild(function(child) { child.ui.toggleCheck(checked); child.attributes.checked = checked; child.fireEvent('checkchange', child, checked); }) }, afterRender: function (t) { treeP2 = t; treeP2.root.expand(true); } } }(9)请求 dataUrl: 'system/resource/getResourceByRole.json?roleId='+record.get('id')
这里是根据角色的id去展示拥有的资源.
(10)Controller类中代码:
/** * 角色已拥有的权限 * @param model * @param roleId */ @RequestMapping("getResourceByRole") public void getResourceByRole(Model model,Integer roleId) { List<TreeNode> listNode =resourceService.getRoleResources(roleId); model.addAttribute("nodes",listNode); model.addAttribute(SUCCESS, true); }(11)在Service类中:
/** * 初始化已有的资源 * @param roleId * @return */ public List<TreeNode> getRoleResources(int roleId){ List<Integer> roleIds= resourceMapper.queryResourceByRole(roleId); List<TreeNode> listChildNode =getChildNodeListByRole(0,roleIds); return listChildNode; } public List<TreeNode> getChildNodeListByRole(int pid,List<Integer> idList){ List<TreeNode> list =resourceMapper.selectChildNodeList(pid); for(TreeNode rn:list){ List<TreeNode> innerList =getChildNodeListByRole(rn.getId(),idList); rn.setChildren(innerList); if(idList.contains(rn.getId())){ rn.setChecked(true); }else{ rn.setChecked(false); } if(rn.getPid().intValue()==0){ rn.setLeaf(false);//第一级全部不是叶子 }else{ rn.setLeaf(innerList.size()==0?true:false); } } return list; }(12)在Mapper类中:
/** * 根据角色查权限 * @return */ List<Integer> queryResourceByRole(int roleId); /** * 找出子节点 * @param pid * @return */ List<TreeNode> selectChildNodeList(int pid);(13)在XML中的SQL语句:
<select id="queryResourceByRole" parameterType="Integer" resultType="Integer">
SELECT
resource_id
FROM
sb_role_resource
WHERE
role_id=#{roleId}
</select>
<select id="selectChildNodeList" resultType="TreeNode" parameterType="Integer">
SELECT
id,name,pid,display_name as text,type,create_time as createTime,sort
FROM
sb_resource
WHERE pid=#{pid}
</select>
(14)前台的EXT展示图:
(15)这样就把两种情况下的树形都可以展示了,一种是查询所有的节点数据,另一种是根据条件展示拥有的节点的数据。