一个ExtJS实例

聊聊ExtJS
这几天接触了一个项目 前台用的是extjs 发现这个东西还是有点意思的 
就把前台的部分 剥离了下来 有兴趣的朋友可以当做模板学习

不多说先上效果图


这篇文章 可以看作是ext知识的一个汇总
因此我不想讲太多细碎的知识点 但我会一一之命这些知识点在哪里可以找到
另一方面 ext细碎的知识点确实太多 自己没有精力也不想搞的太清楚 够用就行
我会说一些 我认为最重要的部分
首先 希望大家看看这篇文章
http://www.cnblogs.com/iamlilinfeng/archive/2012/06/26/2563047.html关于ext的布局
在项目里 主要用到了两种布局 accordion BorderLayout
其次还有一个TabPanel 这个大家可以参考 (文库里面的第三页)
http://wenku.baidu.com/link?url=NE2POFUVQ4QopprUDiRmgyj3McqpT8WOJ5yw7Rp59GGa56BBm1lB2aEiaZ-anxgghfm4hTYHpF9mMfLXQSgc92dUV-1B7x4qoxcnzG4Zv5u

先看admin_main.jsp 页面如下


[html]  view plain
  1. <%@ page language="java" pageEncoding="UTF-8"%>  
  2.   
  3. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
  4. <html>  
  5.     <head>  
  6.         <title>资源共享平台</title>  
  7.         <meta http-equiv="pragma" content="no-cache">  
  8.         <meta http-equiv="cache-control" content="no-cache">  
  9.         <meta http-equiv="expires" content="0">  
  10.         <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  
  11.         <meta http-equiv="description" content="This is my page">  
  12.         <link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />  
  13.         <link rel="stylesheet" type="text/css"  
  14.             href="ext/resources/css/ext-all.css" />  
  15.         <script type="text/javascript" src="ext/adapter/ext/ext-base.js"></script>  
  16.         <script type="text/javascript" src="ext/ext-all.js"></script>  
  17.         <script type="text/javascript" src="js/admin_main.js"></script>  
  18.       
  19. <style type="text/css">  
  20. //css省略 详细代码见附件  
  21. </style>  
  22.     </head>  
  23.     <body>  
  24.         <div id="loading-mask"></div>  
  25.         <div id="loading">  
  26.             <div style="text-align: center; padding-top: 25%">  
  27.                 <img src="images/loading32.gif" width="32" height="32"  
  28.                     style="margin-right: 8px;" />  
  29.                 页面加载中......  
  30.             </div>  
  31.         </div>  
  32.     </body>  
  33. </html>  
很简单吧 只用loading这个div里面的图片 大家去images里面看看就知道了 页面会不断播放那个gif同时显示"页面加载中..."
直到整个页面加载完毕
[html]  view plain
  1. <script type="text/javascript" src="js/admin_main.js"></script>  
我们再看看admin_main.js


这部分很长很长 大家有点耐心 我先整体讲一下
从12-67行的代码 显示了后台管理部分的代码
从75-188行的代码 显示的是资源共享的代码
至于两部分中的listener部分 暂时先不管 它处理的是导航树被点击后的效果
从196-213行的代码吧上面两部分用tabPanel 集合起来作为一个整体
同时 注意这部分代码region : 'west'  可以知道这个整体又作为一个borderlayout布局的左边部分
从217-223行的代码 显示的是整个页面的顶部
从227-245行的代码 我们可以认为它定义了一个"类"(或者说是界面也行) 它就是整个屏幕的主题
从246-265部分 用的是继承的知识 我们定义了一个新的组件 MainPanel
可参考下面这篇文章
http://blog.csdn.net/alastormoody/article/details/8251018
mainTabPanel = new MainPanel();
这个很容易理解了 我们的mainTabPanel是MainPanel的一个实例
当然这里也需要一点frame的知识
http://www.w3school.com.cn/tags/tag_frame.asp
现在大家回想12-67 75-188 部分的listener 应该能看懂了

[javascript]  view plain
  1. Ext.BLANK_IMAGE_URL = 'ext/resources/images/default/s.gif';  
  2. Ext.QuickTips.init();  
  3. var menu = null;  
  4. var mainTabPanel = null;  
  5. var rightMenu = null;  
  6.   
  7. Ext.onReady(function(){  
  8.   
  9.     var appUrlData;  
  10.     var appUrlStore;  
  11.   
  12.     var rightRoot = new Ext.tree.AsyncTreeNode({  
  13.                 id : 'rightRoot',  
  14.                 text : '后台管理rightRoot',  
  15.                 expanded : true  
  16.             });  
  17.   
  18.     var rightLoader = new Ext.tree.TreeLoader({  
  19.              dataUrl:'getAdminAppTree.action'  
  20.         });  
  21.     rightLoader.processResponse = function(response, node, callback) {  
  22.         var json = response.responseText;  
  23.         try {  
  24.             json = eval("(" + json + ")");  
  25.             // 从json中获得json数组,这里的appTree与Struts2返回的json对象中的appTree对应  
  26.             var o = json["jsonText"];  
  27.             o = eval("(" + o + ")");  
  28.             if(o==""||o==null){  
  29.                 Ext.getDom("mainframe").contentWindow.location.href = "common/global_error.jsp";  
  30.             }else{  
  31.                 node.beginUpdate();  
  32.                 for (var i = 0, len = o.length; i < len; i++) {  
  33.                     var n = this.createNode(o[i]);  
  34.                     if (n) {  
  35.                         node.appendChild(n);  
  36.                     }  
  37.                 }  
  38.                 node.endUpdate();  
  39.                 if (typeof callback == "function") {  
  40.                         callback(this, node);  
  41.                 }  
  42.             }  
  43.         } catch (e) {  
  44.             this.handleFailure(response);  
  45.         }  
  46.     }  
  47.       
  48.     rightMenu = new Ext.tree.TreePanel({  
  49.                 id : 'rightMenu',  
  50.                 loader : rightLoader,  
  51.                 title : '后台管理rightMenu',  
  52.                 root : rightRoot,  
  53.                 rootVisible : true,  
  54.                 autoHeight : true,  
  55.                 autoScroll : true,  
  56.                 containerScroll : true,  
  57.                 animate : false,  
  58.                 /*frame : true,*/  
  59.                 listeners: {  
  60.                             click: function(n,e) {  
  61.                                 if(n.isLeaf()){       
  62.                                     mainTabPanel.get(0).update('<iframe id="mainframe" scrolling="auto" frameborder="0" width="100%" height="100%" src="'+n.attributes.url+'"></iframe>',false);  
  63.                                     mainTabPanel.setActiveTab(0);                                                             
  64.                                 }  
  65.                             }  
  66.                         }  
  67.             });  
  68.       
  69.       
  70.     //*******************************************//  
  71.       
  72.       
  73.     //资源共享的三个组件 start   end在188左右  
  74.     //其一 (其实每一个组将都是一个treePanel)  
  75.     var appTreeRoot1 = new Ext.tree.AsyncTreeNode({  
  76.                 id : 'appTreeRoot1',  
  77.                 expanded : true  
  78.             });   
  79.     var appTreeLoader1 = new Ext.tree.TreeLoader(  
  80.         {   id:'appTreeLoader1',  
  81.             dataUrl : 'getGroupAppTree.action?appGroupId=1'  
  82.         }  
  83.     );  
  84.     var appTreeMenu1 = new Ext.tree.TreePanel({  
  85.                 id : 'menu1',  
  86.                 loader : appTreeLoader1,  
  87.                 title : ' 资源共享appTreeMenu1',  
  88.                 root : appTreeRoot1,  
  89.                 border : false,  
  90.                 autoScroll : true,//滚动条  
  91.                 useArrows : true,//是否使用箭头样式  
  92.                 animate : true,//展开,收缩动画  
  93.                 rootVisible : false,  
  94.                 /* 
  95.                 enableDD : true, 
  96.                 frame : true, 
  97.                 */  
  98.                 listeners: {  
  99.                             click: function(n,e) {  
  100.   
  101.                                 mainTabPanel.get(0).update('<iframe id="mainframe" scrolling="auto" frameborder="0" width="100%" height="100%" src="'+n.attributes.url+'"></iframe>',false);  
  102.                                 mainTabPanel.setActiveTab(0);  
  103.                             }  
  104.                         }  
  105.             });  
  106.       
  107.     //其二  
  108.     var appTreeRoot2 = new Ext.tree.AsyncTreeNode({  
  109.                 id : 'appTreeRoot2',  
  110.                 expanded : true               
  111.             });   
  112.     var appTreeLoader2 = new Ext.tree.TreeLoader(  
  113.         {   id : 'appTreeLoader2',  
  114.             dataUrl : 'getGroupAppTree.action?appGroupId=2'  
  115.         }  
  116.     );  
  117.     var appTreeMenu2 = new Ext.tree.TreePanel({  
  118.                 id : 'menu2',  
  119.                 loader : appTreeLoader2,  
  120.                 title : ' 资源管理appTreeMenu2',  
  121.                 root : appTreeRoot2,  
  122.                 border : false,  
  123.                 autoScroll : true,//滚动条  
  124.                 useArrows : true,//是否使用箭头样式  
  125.                 animate : true,//展开,收缩动画  
  126.                 rootVisible:false,  
  127.                 /* 
  128.                 enableDD : true, 
  129.                 frame : true, 
  130.                 */  
  131.                 listeners: {  
  132.                             click: function(n,e) {  
  133.                                 mainTabPanel.get(0).update('<iframe id="mainframe" scrolling="auto" frameborder="0" width="100%" height="100%" src="'+n.attributes.url+'"></iframe>',false);  
  134.                                 mainTabPanel.setActiveTab(0);  
  135.                                 // Ext.getDom("mainframe").contentWindow.location.href =n.attributes.url;  
  136.                             }  
  137.                         }  
  138.             });  
  139.       
  140.     //其三          
  141.     var appTreeRoot10 = new Ext.tree.AsyncTreeNode({  
  142.                 id : 'appTreeRoot5',  
  143.                 expanded : true  
  144.             });   
  145.     var appTreeLoader10 = new Ext.tree.TreeLoader(  
  146.         {   id : 'appTreeLoader5',  
  147.             dataUrl : 'getGroupAppTree.action?appGroupId=10'  
  148.         }  
  149.     );  
  150.     var appTreeMenu10 = new Ext.tree.TreePanel({  
  151.                 id : 'menu10',  
  152.                 loader : appTreeLoader10,  
  153.                 title : ' 账号管理',  
  154.                 root : appTreeRoot10,  
  155.                 border : false,  
  156.                 autoScroll : true,//滚动条  
  157.                 useArrows : true,//是否使用箭头样式  
  158.                 animate : true,//展开,收缩动画  
  159.                 rootVisible : false,  
  160.                 /* 
  161.                 enableDD : true, 
  162.                 frame : true, 
  163.                 */  
  164.                 listeners: {  
  165.                             click: function(n,e) {  
  166.                                 mainTabPanel.get(0).update('<iframe id="mainframe" scrolling="auto" frameborder="0" width="100%" height="100%" src="'+n.attributes.url+'"></iframe>',false);  
  167.                                 mainTabPanel.setActiveTab(0);  
  168.                                   
  169.                                 // Ext.getDom("mainframe").contentWindow.location.href =n.attributes.url;  
  170.                             }  
  171.                         }  
  172.             });  
  173.               
  174.     var leftAppTreeMenu = new Ext.Panel({  
  175.         id : 'leftAppTreeMenu',  
  176.         layout : 'accordion',  
  177.         border:false,  
  178.         title:'资源共享asdfasdf',  
  179.         layoutConfig:{  
  180.             titleCollapse:true,  
  181.             animate:true,  
  182.             activeOnTop:false},  
  183.         items:[appTreeMenu1,appTreeMenu2,appTreeMenu10]   
  184.       
  185.         });   
  186.       
  187.     // 开始于75资源共享 三个组件 集合起来       使用acordion视图  
  188.      
  189.       
  190.     //menu是整个左边导航   
  191.     //注意menu是tabPanel  
  192.     //leftapptreemenu是panel  
  193.     //rightMenu是treemenu  与leftapptreemenu的三个组件是一个类型  
  194.     //在menu之上 还有一个viewport 它作为全局界面 使用borderlayout  
  195.     //menu的region是west  
  196.     menu = new Ext.TabPanel( {  
  197.         id : 'menu',  
  198.         activeTab : 0,  
  199.         width : 310,  
  200.         split : true,  
  201.         region : 'west',  
  202.         // deferredRender : false,  
  203.         resizeTabs : true,  
  204.         minTabWidth : 100,  
  205.         tabWidth : 100,  
  206.         frame : true,  
  207.         items : [leftAppTreeMenu,rightMenu],  
  208.         listeners:{  
  209.             tabchange:function(t, tab) {  
  210.                 tab.doLayout();  
  211.             }  
  212.         }  
  213.     });  
  214.    
  215.   
  216.       
  217.    var northpanel = new Ext.Panel({  
  218.                             id:'north',  
  219.                             region:'north',  
  220.                             layout:'column',  
  221.                             height:100,  
  222.                             html:'<div style="width:100%; background: url(images/main_title_bg.gif) repeat-x;"><img src="images/main_title.gif" /><span id="logout"><a href="javascript:void(0)" οnclick="popHelp()">用户手册</a> | <a href="logout.action" target="_top">注销</a></span></div>'  
  223.                             });  
  224.      
  225.   
  226.       
  227.     MainPanel = function() {  
  228.         this.openTab = function(panel, id) {  
  229.             var o = (typeof panel == "string" ? panel : id || panel.id);  
  230.             var tab = this.getComponent(o);  
  231.             if (tab) {  
  232.                 this.setActiveTab(tab);  
  233.             } else if (typeof panel != "string") {  
  234.                 panel.id = o;  
  235.                 var p = this.add(panel);  
  236.                 this.setActiveTab(p);  
  237.             }  
  238.         };  
  239.         this.closeTab = function(panel, id) {  
  240.             var o = (typeof panel == "string" ? panel : id || panel.id);  
  241.             var tab = this.getComponent(o);  
  242.             if (tab) {  
  243.                 this.remove(tab);  
  244.             }  
  245.         };  
  246.         MainPanel.superclass.constructor.call(this, {  
  247.                     id : 'main',  
  248.                     region : 'center',  
  249.                     margins : '0 5 5 0',  
  250.                     resizeTabs : true,  
  251.                     minTabWidth : 180,  
  252.                     tabWidth : 180,  
  253.                     enableTabScroll : true,  
  254.                     activeTab : 0,  
  255.                     /*draggable : true,*/  
  256.                     items : {  
  257.                         id : 'homePage',  
  258.                         title : '主页',  
  259.                         closable : false,  
  260.                         html : '<iframe id="mainframe" name="mainframe" scrolling="yes" frameborder="0" width="100%" height="100%" src="common/blank.html"></iframe>'  
  261.                     }  
  262.                 });  
  263.     };  
  264.       
  265.     Ext.extend(MainPanel, Ext.TabPanel);  
  266.       
  267.     mainTabPanel = new MainPanel();  
  268.       
  269.       
  270.     var viewport = new Ext.Viewport({  
  271.                 layout : 'border',  
  272.                 items : [northpanel,mainTabPanel,menu]  
  273.             });  
  274.       
  275.             
  276. });  


这个主面板 最开始的时候引用的src是common/blank.html 白板一张而已

[javascript]  view plain
  1. var viewport = new Ext.Viewport({  
  2.             layout : 'border',  
  3.             items : [northpanel,mainTabPanel,menu]  
  4.         });  
ViewPort不必细究 就是一个全屏的window而已
看他的布局 大家就应该明白 这个viewPort就是我们看到的界面

前后台交互用的是json 与struts 这里就不再赘述相关知识点了 网上资料一搜一大堆
下面是响应的action处理方法

[java]  view plain
  1.   /** 
  2.  * 读取系统管理员"后台管理"版块的目录树结构 
  3.  */  
  4. public String getAdminAppTree() throws Exception {  
  5.     System.out.println("getAdminAppTree");  
  6.     this.jsonText = "[{'id':6,'text':'角色管理','children':[{'id':61,'text':'创建角色','leaf':true,'url':'modules/role/creatRole/creatRole.jsp'},{'id':62,'text':'设定角色应用权限','leaf':true,'url':'modules/role/setRoleApp/setRoleApp.jsp'},{'id':64,'text':'删除角色','leaf':true,'url':'modules/role/deleteRole/deleteRole.jsp'}]},{'id':7,'text':'用户管理','children':[{'id':71,'text':'创建用户','leaf':true,'url':'modules/user/creatUser/creatUser.jsp'},{'id':72,'text':'用户信息管理','leaf':true,'url':'modules/user/viewUserInf/viewUserInf.jsp'},{'id':73,'text':'设定用户所属角色','leaf':true,'url':'modules/user/setUserRole/setUserRole.jsp'}]}]";  
  7.     System.out.println("jsonText=    "+this.jsonText);  
  8.   
  9.     return SUCCESS;  
  10. }  
  11.   
  12. /** 
  13.  * 根据GroupId,读取该用户在该应用组内的所有应用 
  14.  */  
  15. public void getGroupAppTree() throws Exception {  
  16.     JSONArray ja=null;  
  17.     System.out.println("getGroupAppTree  默认");  
  18.     if (appGroupId==10) {  
  19.         System.out.println("getGroupAppTree  10");  
  20.         ja=  new JSONArray("[{'id':11,'text':'标准化资源共享','leaf':true,'url':'modules/file/baseShare/baseShare.jsp'},{'id':12,'text':'标准化工具','leaf':true,'url':'modules/file/tool/tool.jsp'},{'id':13,'text':'资源环境共享','leaf':true,'url':'modules/file/webShare/webShare.jsp'}]");  
  21.     }  
  22.     if (appGroupId==2) {  
  23.         System.out.println("getGroupAppTree  2");  
  24.         ja=new JSONArray("[{'id':21,'text':'资源检索','leaf':true,'url':'modules/Manager/search/search.jsp'},{'id':23,'text':'资源审核','leaf':true,'url':'modules/Manager/manager/manager.jsp'},{'id':24,'text':'资源删除','leaf':true,'url':'modules/Manager/delete/delete.jsp'},{'id':27,'text':'资源结算','leaf':true,'url':'modules/Manager/cal/cal.jsp'}]");  
  25.     }  
  26.     if (appGroupId==1) {  
  27.         System.out.println("getGroupAppTree  1");  
  28.         ja=new JSONArray("[{'id':101,'text':'修改账号信息','leaf':true,'url':'modules/account/changeAccountInf/changeAccountInf.jsp'},{'id':102,'text':'修改账号密码','leaf':true,'url':'modules/account/changePassword/changePassword.jsp'},{'id':104,'text':'权限申请','leaf':true,'url':'modules/account/applyPermission/applyPermission.jsp'}]");  
  29.     }  
  30.       
  31.       
  32.     PrintWriter out;  
  33.     this.response.setContentType("text/html;charset=UTF-8");  
  34.     out = this.response.getWriter();  
  35.     out.print(ja.toString());  
  36.     out.close();  
  37. }  
web.xml,struts.xml这里就不写了 看附件

源码下载

http://download.csdn.net/detail/dlf123321/7823325



参考资料

http://www.cnblogs.com/iamlilinfeng/archive/2012/06/26/2563047.html

http://wenku.baidu.com/link?url=NE2POFUVQ4QopprUDiRmgyj3McqpT8WOJ5yw7Rp59GGa56BBm1lB2aEiaZ-anxgghfm4hTYHpF9mMfLXQSgc92dUV-1B7x4qoxcnzG4Zv5u

http://blog.csdn.net/alastormoody/article/details/8251018

http://www.w3school.com.cn/tags/tag_frame.asp


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值