extjs 的权限问题 要求控制的对象是 菜单,按钮,URL |
本文标签:extjs,权限问题 解题思路1 : 重载Connection类 复制代码 代码如下: //此处重载了Cunnection方法,用来拦截client与Server的交 互, //后台acegi拦截用户请求后,如果无权限,返回403.jsp;如果没登录,返回login.jsp; //通过Acegi拦截 后,才返回用户想要的Json结果 Ext.override(Ext.data.Connection, { handleResponse : Ext.data.Connection.prototype.handleResponse.createInterceptor( function(response) { var resText=response.responseText; if (resText.length>10) { resText=resText.substr(0,9); } if (resText==<!--login){ window.top.location.href = topURL+"/login.jsp"; } else if (resText==<!--deny-){ if (resText==<!--deny-){ Ext.Msg.show({ title : 错误提示, msg : 禁止访问此功能,请和系统管理员联系, buttons : Ext.Msg.OK, icon : Ext.Msg.INFO }); }; } else if (resText==<!--404--){ Ext.Msg.show({ title : 错误提示, msg : 页面未找到, buttons : Ext.Msg.OK, icon : Ext.Msg.INFO }); } }) }); 解题思路2: server端返回菜单json数据 我的菜单用tree来做的,在初始化主页面时先初始化菜单, 复制代码 代码如下: loader : new Ext.tree.TreeLoader({ dataUrl : getJsonMenus.do }), 这个getJsonMenus.do返回菜单json数据,在strut2中的配置为: <action name="getJsonMenus" class="jsonSystemAction" method="getJsonMenus"> <result type="json"> <param name="root">menus</param> </result> </action> menus是个list<JsonMenu>, JsonMenu的属性为: private String text; private boolean expanded; private String id; private boolean leaf; private List<JsonMenu> children; getJsonMenus.do 返回的格式是可以满足tree的格式要求的 。 js代码如下 复制代码 代码如下: Ext.onReady(function() { setTimeout(function() { Ext.get(loading).remove(); Ext.getDom(header).style.visibility = visible; var vp = new Ext.Viewport({ layout : border, defaults : { collapsible : true, split : true }, items : [{ xtype : box, region : north, applyTo : header, height : 30, split : false }, { title : currentUser, id : accordion-panel, layout : border, region : west, margins : 2 0 5 5, width : 200, minSize : 200, maxSize : 250, bodyStyle : background-color:#DFE8F6, defaults : { border : false }, bbar : [{ text : 开始, iconCls : icon-plugin, menu : new Ext.menu.Menu({ items : [{ text : 关于系统, iconCls : icon-info, handler : function() { new Ext.Window({ closeAction : close, resizable : false, bodyStyle : padding: 7, modal : true, title : 关于本系统, html : 本系统采用目前较为流行的技术实现,<br>前台使用了ExtJs技术,所以实现了跨浏览器<br> + 本程序在IE6,IE7,FireFox3均测试通过!<br><br>主要技术: Struts2 + Spring + iBatis + ExtJs<br><br> + 数 据 库: Oracle 9i, width : 300, height : 200 }).show(); } }, { text : 退出系统, iconCls : icon-delete, handler : function() { Ext.Msg.confirm(操作提示, 您确定要退出本系统?, function(btn) { if (yes == btn) { Ext.Ajax.request({ url : logout.do, success : function() { location = /; }, failure : function() { Ext.Msg.show({ title : 错误提示, msg : 退出系统失败!, icon : Ext.Msg.ERROR, buttons : Ext.Msg.OK }); } }); } }); } }] }) }], items : [{ layout : accordion, region : center, items : [{ title : 导航菜单, iconCls : icon-nav, border : false, items : [{ xtype : treepanel, border : false, rootVisible : false, autoScroll : true, loader : new Ext.tree.TreeLoader({ dataUrl : getJsonMenus.do }), root : new Ext.tree.AsyncTreeNode(), listeners : { click : function(n) { try { var sn = this.selModel.selNode || {}; if (n.leaf && n.id != sn.id) { Ext.getCmp(content-panel).layout.setActiveItem(n.id.substring(0, n.id .indexOf(-)) + -panel); } } catch (e) { } } } }] },{ title : 系统设置, iconCls : icon-nav }] }] }, { id : content-panel, region : center, layout : card, margins : 2 5 5 0, activeItem : 0, border : false, items : [start, p_company, p_user, p_dept, p_system, p_subject, p_category, p_resource] }] }); }, 250); }); 这样就得到了菜单,还有网友提出了异步菜单解决方法,我也把它列到下面 解题思路3 : 同步加载所有的TAG,用hidden属性控制显示 所有的tag必须要同步加载后才可以控制component的hidden属性,异步加载不好用 。 同步加载的方法如下: 复制代码 代码如下: //FUTURE_TAG全局的TAG控制类, 控制的组件的hidden属性,key=TAG的名字,value=true(组件隐藏),false(组件显示) var FUTURE_TAG={tbar1: false, tbar2: true}; var conn = Ext.lib.Ajax.getConnectionObject().conn; conn.open("GET", getJsonTags.do,false); conn.send(null); future_tag= eval(( + conn.responseText + )); 在js中TAG的用法如下: 复制代码 代码如下: var btn_add_system = new Ext.Button({ text : 添加, iconCls : icon-add, hidden: FUTURE_TAG.system_add, handler : function() { window_add_system.show(); } }); getJsonTags.do 返回一个Map对象,key是TAG名字,value是boolean java的写法如下: 复制代码 代码如下: tagMap=new HashMap<String,Boolean>(); for (int i=0;i<allTagList.size();i++){ tagMap.put(allTagList.get(i).getResString(), true); } strut2配置如下: 复制代码 代码如下: <action name="getJsonTags" class="jsonSystemAction" method="getJsonTags"> <result type="json"> <param name="root">tagMap</param> </result> </action> 这样就可以在后台控制前台的组件是否显示了,从而达到了我们的目的 。 解决思路4: 通过ajax读取服务器端的权限值,返回这样的数据: {tbar1: false, tbar2: true} 然后在extjs中: var vResult = eval(( + ajaxText + )); //得到{tbar1: false, tbar2: true} 这样就可以直接给tbar赋值了 disabled: vResult.tbar1 disabled: vResult.tbar2 解决思路5: 设置模块权限用于设置用户可以操作的权限 。允许设置用户对模块的可操作与不可操作 。 弹出设置权限子窗体 设置权限之前须选择一个用户 。 Js代码 复制代码 代码如下: var row = grid_user.getSelectionModel().getSelected(); if(!row){ alert(对不起,您还未选择数据!); return; } var row = grid_user.getSelectionModel().getSelected(); if(!row){ alert(对不起,您还未选择数据!); return; } 创建一棵树,树放置在弹出窗体的中央 。 Js代码 复制代码 代码如下: var root=new Ext.tree.TreeNode({ id:"root", text:"所有操作", checked:false, iconCls:task-folder }); var tree=new Ext.tree.TreePanel({ frame:false, region:center, root:root, animate:true, enableDD:false, border:false, rootVisible:true, autoScroll:true }); var root=new Ext.tree.TreeNode({ id:"root", text:"所有操作", checked:false, iconCls:task-folder }); var tree=new Ext.tree.TreePanel({ frame:false, region:center, root:root, animate:true, enableDD:false, border:false, rootVisible:true, autoScroll:true }); 创建弹出子窗体 。 Js代码 复制代码 代码如下: var win = new Ext.Window({ title:设置模块权限, closable:true, width:300, height:500, plain:true, layout:border, modal:true, items:[tree] }); win.show(this); var win = new Ext.Window({ title:设置模块权限, closable:true, width:300, height:500, plain:true, layout:border, modal:true, items:[tree] }); win.show(this); 在加载数据期间,给予提示 。 Js代码 复制代码 代码如下: Ext.MessageBox.show({ title:请稍候, msg:正在加载数据,请耐心等待..., progress:true }); Ext.MessageBox.show({ title:请稍候, msg:正在加载数据,请耐心等待..., progress:true }); 将根节点,所选择的用户行,父节点标志作为参数调用方法 。 Js代码 getNodes(row,root,root); getNodes(row,root,root); 从后台中取得数据并以树形式在客户端展现 方法定义与方法内容 。 Js代码 复制代码 代码如下: function getNodes(row,root,parent){ //... } function getNodes(row,root,parent){ //...} JSON 数据的定义 。 Js代码 复制代码 代码如下: var record_pri = new Ext.data.Record.create([ {name:modelId}, {name:modelName}, {name:sort}, {name:canUse}, {name:privilegeId} ]); var store_pri = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({url:../}), reader: new Ext.data.JsonReader({root:rows},record_pri) }); var record_pri = new Ext.data.Record.create([ {name:modelId}, {name:modelName}, {name:sort}, {name:canUse}, {name:privilegeId} ]); var store_pri = new Ext.data.Store({ proxy: new Ext.data.HttpProxy({url:../}), reader: new Ext.data.JsonReader({root:rows},record_pri) }); 无刷新请求,获取数据并展现出来;并添加事件监听 。当点击树某一节点时,判断是否已经从后台取得数据,如果还没有取则从后台获取数据,再根据返回的数据判断是叶子节点还是非叶子节点 。然后以不同的方式展现与处理 。 叶子节点和非叶子节点展现时,使用的图标不同 。叶子节点没有添加单击事件,而非叶子节点添加了单击事件 。 Js代码 复制代码 代码如下: Ext.Ajax.request({ url:http://www.cnblogs.com/../privilegeAction.do?method=list, params:{ userId:row.get(userId), parentId:parent }, success:function(response, request){ Ext.MessageBox.hide(); var res = Ext.util.JSON.decode(response.responseText); store_pri.loadData(res); for(var i=0;i<store_pri.getCount();i++){ var rec = store_pri.getAt(i); var canuse = (rec.get(canUse)==是?true:false); var modid = rec.get(privilegeId) + -id- + rec.get(modelId); var node; if(rec.get(sort)==菜单){ node = new Ext.tree.TreeNode({ text:rec.get(modelName), id:modid, checked:canuse, iconCls:task-folder }); node.on(click,function(node){ if(node.firstChild==null){ getNodes(row,node,get_mod_id(node.id)); } }); } else { node = new Ext.tree.TreeNode({ text:rec.get(modelName), id:modid, checked:canuse, iconCls:task }); } node.on(checkchange,function(node,check){ Ext.Ajax.request({ url:http://www.cnblogs.com/../privilegeAction.do?method=save2, params:{ privilegeId:get_rec_id(node.id), canuse:(check?是:否) }, success:function(response, request){ }, failure:function(){ Ext.MessageBox.hide(); alert(sorry!); } }); }); root.appendChild(node); } root.expand(); }, failure:function(){ Ext.MessageBox.hide(); alert(sorry!); } }); Ext.Ajax.request({ url:http://www.cnblogs.com/../privilegeAction.do?method=list, params:{ userId:row.get(userId), parentId:parent }, success:function(response, request){ Ext.MessageBox.hide(); var res = Ext.util.JSON.decode(response.responseText); store_pri.loadData(res); for(var i=0;i<store_pri.getCount();i++){ var rec = store_pri.getAt(i); var canuse = (rec.get(canUse)==是?true:false); var modid = rec.get(privilegeId) + -id- + rec.get(modelId); var node; if(rec.get(sort)==菜单){ node = new Ext.tree.TreeNode({ text:rec.get(modelName), id:modid, checked:canuse, iconCls:task-folder }); node.on(click,function(node){ if(node.firstChild==null){ getNodes(row,node,get_mod_id(node.id)); } }); } else { node = new Ext.tree.TreeNode({ text:rec.get(modelName), id:modid, checked:canuse, iconCls:task }); } node.on(checkchange,function(node,check){ Ext.Ajax.request({ url:http://www.jb51.net/../privilegeAction.do?method=save2, params:{ privilegeId:get_rec_id(node.id), canuse:(check?是:否) }, success:function(response, request){ }, failure:function(){ Ext.MessageBox.hide(); alert(sorry!); } }); }); root.appendChild(node); } root.expand(); }, failure:function(){ Ext.MessageBox.hide(); alert(sorry!); } }); 当非叶子节点被点击时,递归地调用方法来获取孩子节点 。 获取行的ID和模块的ID 。树的节点将行的ID和模块的ID一起取出来了 。不然的话,如果只取得模块ID,而不取行ID,那么在修改的时候,则不能进行正确的修改 。 Js代码 复制代码 代码如下: function get_rec_id(str){ var arr = str.split(-id-); return arr[0]; } function get_mod_id(str){ var arr = str.split(-id-); return arr[1]; } |