VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > JavaScript教程 >
  • [转]extjs 的权限问题。要求控制的对象是 菜单,按钮,URL

这两天在解决extjs 的权限问题。要求控制的对象是  菜单,按钮,URL

解题思路1 : 重载Connection类

 由于extjs和server端交互全都是 json格式的数据交互,server端不会控制页面的跳转,页面跳转,提示功能全都有extjs来完成。

   extjs和server端的交互方法全都是继承自 Ext.data.Connection,这个类中可以拦截所有和server端交互的方法。

   server端的权限控制用acegi做的,如果没通过acegi的验证,没有授权会返回到403.jsp,需要重登录会返回到 login.jsp。

   因此重载Connection类,并改写其中的 handleResponse 方法,判断返回的结果是否是 403.jsp,login.jsp, 如果是就进行相应的控制,如果是正常的返回数据就继续向下执行。

     我个人在403.jsp  和login.jsp 的第一行加上了 注释代码<!--权限控制自定义关键字-->,就是靠这个关键字来工作的

   ,代码如下:

 //此处重载了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>'
           + '数&nbsp;&nbsp;据&nbsp;&nbsp;库: 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代码

   1. var root=new Ext.tree.TreeNode({   
   2.                 id:"root",   
   3.                 text:"所有操作",   
   4.                 checked:false,   
   5.                 iconCls:'task-folder'  
   6.           });   
   7.              
   8.           var tree=new Ext.tree.TreePanel({   
   9.             frame:false,   
  10.             region:'center',   
  11.             root:root,   
  12.             animate:true,   
  13.             enableDD:false,   
  14.             border:false,   
  15.             rootVisible:true,   
  16.             autoScroll:true  
  17.          });  

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代码

   1. var win = new Ext.Window({   
   2.             title:'设置模块权限',   
   3.             closable:true,   
   4.             width:300,   
   5.             height:500,   
   6.             plain:true,   
   7.             layout:'border',   
   8.             modal:true,   
   9.             items:[tree]   
  10.         });   
  11.         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代码

   1. Ext.MessageBox.show({   
   2.             title:'请稍候',   
   3.             msg:'正在加载数据,请耐心等待...',   
   4.             progress:true              
   5.         });  

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代码

   1. Ext.Ajax.request({   
   2.             url:'http://www.cnblogs.com/../privilegeAction.do?method=list',   
   3.             params:{   
   4.                 userId:row.get('userId'),   
   5.                 parentId:parent   
   6.             },   
   7.             success:function(response, request){   
   8.                 Ext.MessageBox.hide();   
   9.                 var res = Ext.util.JSON.decode(response.responseText);   
  10.                 store_pri.loadData(res);   
  11.                 for(var i=0;i<store_pri.getCount();i++){   
  12.                     var rec = store_pri.getAt(i);   
  13.                     var canuse = (rec.get('canUse')=='是'?true:false);          
  14.                     var modid = rec.get('privilegeId') + '-id-' + rec.get('modelId');   
  15.                     var node;   
  16.                     if(rec.get('sort')=='菜单'){   
  17.                         node = new Ext.tree.TreeNode({   
  18.                             text:rec.get('modelName'),   
  19.                             id:modid,   
  20.                             checked:canuse,   
  21.                             iconCls:'task-folder'  
  22.                         });   
  23.                         node.on('click',function(node){   
  24.                             if(node.firstChild==null){   
  25.                                 getNodes(row,node,get_mod_id(node.id));   
  26.                              }   
  27.                         });   
  28.                     } else {   
  29.                         node = new Ext.tree.TreeNode({   
  30.                             text:rec.get('modelName'),   
  31.                             id:modid,   
  32.                             checked:canuse,   
  33.                             iconCls:'task'  
  34.                         });   
  35.                     }   
  36.                     node.on('checkchange',function(node,check){   
  37.                         Ext.Ajax.request({   
  38.                             url:'http://www.cnblogs.com/../privilegeAction.do?method=save2',   
  39.                             params:{   
  40.                                 privilegeId:get_rec_id(node.id),   
  41.                                 canuse:(check?'是':'否')   
  42.                             },   
  43.                             success:function(response, request){   
  44.                                
  45.                             },   
  46.                             failure:function(){   
  47.                                 Ext.MessageBox.hide();   
  48.                                 alert('sorry!');   
  49.                             }   
  50.                         });        
  51.                     });   
  52.                     root.appendChild(node);   
  53.                 }   
  54.                 root.expand();   
  55.             },   
  56.             failure:function(){   
  57.                 Ext.MessageBox.hide();   
  58.                 alert('sorry!');   
  59.             }   
  60.         });       

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!');            }        });     

 

当非叶子节点被点击时,递归地调用方法来获取孩子节点。

 

获取行的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];   
       } 

 出处:https://www.cnblogs.com/chillsrc/archive/2010/03/09/1681406.html


相关教程