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

这个主面板 最开始的时候引用的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. return SUCCESS;
  9. }
  10. /**
  11. * 根据GroupId,读取该用户在该应用组内的所有应用
  12. */
  13. public void getGroupAppTree() throws Exception {
  14. JSONArray ja=null;
  15. System.out.println("getGroupAppTree  默认");
  16. if (appGroupId==10) {
  17. System.out.println("getGroupAppTree  10");
  18. 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'}]");
  19. }
  20. if (appGroupId==2) {
  21. System.out.println("getGroupAppTree  2");
  22. 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'}]");
  23. }
  24. if (appGroupId==1) {
  25. System.out.println("getGroupAppTree  1");
  26. 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'}]");
  27. }
  28. PrintWriter out;
  29. this.response.setContentType("text/html;charset=UTF-8");
  30. out = this.response.getWriter();
  31. out.print(ja.toString());
  32. out.close();
  33. }

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


一个ExtJS实例的更多相关文章

  1. ExtJS实例1

    1.创建一个Extjs的Window,用ajax请求HTML文件,并执行HTML的代码和脚本 窗体中文字是从一个HTML中获取,并且HTML中执行脚本使窗体高亮1秒 主页面: <!DOCTYPE ...

  2. Android 只开启一个Activity实例

    在一个Activity中,多次调用startActivity()来启动另一个Activity,要想只生成一个Activity实例,方法有两种. 方法一:设置起动模式 一个Activity有四种启动模式 ...

  3. 将oracle冷备份恢复到另外一个数据库实例中

    因更换服务器需要将Oracle数据库转移到另外台Oracle中.说明: 1.测试环境为:windows server2003 和 oracle 10g. 2.2台服务器安装的程序目录一样,数据目录不一 ...

  4. 第一个python实例--监控cpu

    #第一个python实例:监控cpu #/bin/bash/env Python from __future__ import print_function from collections impo ...

  5. servlet的一个web容器中有且只有一个servlet实例或有多个实例的理解1

    servlet的一个web容器中有且只有一个servlet实例或有多个实例的理解 (2013-06-19 19:30:40) 转载▼     servlet的非线程安全,action的线程安全 对提交 ...

  6. 12C RAC中的一个数据库实例自动crash并报ORA-27157、ORA-27300等错误

    rhel7.2上安装12C RAC数据库后,其中一个数据库实例经常会自动crash.查看alert日志发现以下错误信息: Errors in file /d12/app/oracle/diag/rdb ...

  7. 一个 XSD 实例

    一个 XSD 实例 本节会为您演示如何编写一个 XML Schema.您还将学习到编写 schema 的不同方法. XML 文档 让我们看看这个名为 "shiporder.xml" ...

  8. Asp.Net MVC是否针对每次请求都重新创建一个控制器实例

    一.Asp.Net MVC是否针对每次请求都重新创建一个控制器实例 默认情况下,答案是确定的. ControllerBuilder类 ControllerBuilder.Current用户获取默认的控 ...

  9. 如何让Windows程序只运行一个程序实例?

    要实现VC++或者MFC只运行一个程序实例,一般采用互斥量来实现,即首先用互斥量封装一个只运行一个程序实例的函数接口: HANDLE hMutex = NULL; void MainDlg::RunS ...

随机推荐

  1. DP测试总结

    T1:三取方格数 题目描述 设有N*N的方格图,我们将其中的某些方格填入正整数,而其他的方格中放入0.某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角.在走过的路上,他取走了方格中的数. ...

  2. POJ 3415 不小于k的公共子串的个数

    Common Substrings Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 9248   Accepted: 3071 ...

  3. [bzoj4763]雪辉&[bzoj4812][Ynoi2017]由乃打扑克

    来自FallDream的博客,未经允许,请勿转载,谢谢. cut掉部分题面. 给一个n个点的树,点有点权,有m次询问,每次询问多条链的并有多少种不同的点权以及它的mex mex就是一个集合中最小的没有 ...

  4. 【集训第三天·疯狂训练】哦,顺带学习了manacher

    虽然说是疯狂训练吧,但是也没写多少题,就把伸展树的操作熟悉了一下,ac了5个题目. 一整天没啥可吐槽的,除了昨天在机房打游戏的某位朋友翻车后和教练谈了谈心2333 说题吧.. 1.BZOJ1208 H ...

  5. c语言第五次作业0

    ---恢复内容开始--- (一)改错题 输出华氏摄氏温度转换表:输入两个整数lower和upper,输出一张华氏摄氏温度转换表,华氏温度的取值范围是{lower,upper},每次增加2℉.计算公式如 ...

  6. SQL之DISTINCT

    警告:不能部分使用DISTINCT. DISTINCT关键字作用于所有的列,不仅仅是跟在其后的那一列.例如,你指定SELECT DISTINCT vend_id, prod_price,除非指定的两列 ...

  7. 重构:从Promise到Async/Await

    摘要: 夸张点说,技术的发展与历史一样,顺之者昌,逆之者亡.JS开发者们,赶紧拥抱Async/Await吧! GitHub仓库: Fundebug/promise-asyncawait 早在半年多之前 ...

  8. MFC回车事件

    这是一个使用MFC开发关于设备控制的windows应用程序 通过该项目我学到的内容: 继承的好处 应用程序的界面是与应用程序的代码有一定的对应关系的,界面中不同的控件对应不同的类,首先就是需要一个对话 ...

  9. Dockerfile的指令

    指令的一般格式为 INSTRUCTION arguments,指令包括 FROM.MAINTAINER.RUN 等. FROM 格式为 FROM <image>或FROM <imag ...

  10. 自己创建一个android studio在线依赖compile

    我正参加2016CSDN博客之星评选麻烦帮下 奖品我随机送给投票者(写一个随机数抽取) http://blog.csdn.net/vote/candidate.html?username=qfanmi ...