最近也終於使用ext做了一個小的web項目。第一次使用ext做項目畢竟經驗不足,僅記下一些開發思路和需要注意的地方。
Ext Js 2.2+Spring 2.5,沒有使用struts,hibernate
1)目錄結構
a)js部分
根目錄下建立/js/ext/目錄,存放所有和ext相關的js文件。/js/ext/目錄下可建立ext相關子目錄
/js/ext/adapter/ — 存放適配器jquery,prototype,yui。。。
/js/ext/experimental/ — 存放ext一些未正式推出的組件,可參考ext開發包examples例子部分。
/js/ext/plugins/ — 存放ext擴展組件,例如ext的patch文件,ext主題,擴展組建等等。
/js/ext/resources/ — 不用說了,ext開發包中的resources目錄直接拷貝。
/js/ — 目錄下可以放一些最常用 的js文件。
/js/ext/ — 目錄下放置ext-all.js,ext-base.js,ext-lang-zh_CN.js,ext核心文件;
b)模塊部分
根目錄下建立/module/文件夾,每個模塊在/module/目錄下新建文件夾,例如:
/module/comment/ — 評論模塊
/module/stat/ — 統計模塊
每個模塊目錄下新建js目錄存放當前模塊需要引用的js文件,例如/module/comment/js/comment.js
爲簡化開發不使用struts,直接使用jsp代替struts;每個模塊下新建action.jsp替代structs接受
ext ajax請求,action.jsp不負責頁面的顯示。只負責service層方法調用及請求跳轉。
c)權限部分
根目錄下直接建一個security目錄完事。
2)基本佈局及權限
border佈局,center區域使用TabPanel組建增加新的iframe窗口裝載系統不同模塊。
暫不在意iframe的效率問題,儘可能做到每個系統模塊+UI部分的獨立。
初始化佈局時TabPanel組件中添加默認的歡迎登錄頁面,解決TabPanel組件添加新窗口時高度增加的bug。
權限系統設計參考spring security建議的數據庫設計,項目後期可與spring security整合。
3)用戶訪問超時
解決兩種情況下的用戶訪問超時。
a)普通http請求的session超時。
b)異步http請求的session超時,使用ext後大部分的界面刷新都是異步的ajax請求。
不管是那種類型的http請求總是可以由一個過濾器來捕捉。
分類:普通http請求的header參數中沒有x-requested-with:XMLHttpRequest頭信息,而異步的有。
其實對於常見的ajax框架,header中還有標示自己身份的header信息。
對於普通的http請求,發現session超時後直接重定向到一個超時頁面,顯示訪問超時。
對於異步http請求,發現session超時後則向請求的response中寫入特定的超時頭信息,客戶端ajax對象檢測
頭信息,發現有超時狀態標誌後調用顯示超時信息的javascript方法,提示用戶訪問超時。
服務器端session超時後在過濾器中爲response添加新的頭信息,標記該請求超時:
- if(r.getHeader("x-requested-with")!=null
- && r.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")){
- response.setHeader("sessionstatus","timeout");
- }
使用Ext.Ajaxt對象完成異步請求的交互,Ext.Ajax是單實例對象(非常重要,全局單一Ext.Ajax實例!)。
註冊Ext.Ajax的requestcomplete事件,每個ajax請求成功後首先響應該事件。在該事件的回調函數裏面判斷
訪問請求是否超時。使用Ext.Ajax對象的好處是,只需要引入一個包含了幾行超時處理代碼的js文件,就可以
爲當前應用增加超時處理功能,原有代碼不需要做任何修改。
使用Ext.Ajaxt對象完成異步請求交互,假如checkUserSessionStatus是你的回調方法,每個頁面引用:
- Ext.Ajax.on('requestcomplete',checkUserSessionStatus, this);
- function checkUserSessionStatus(conn,response,options){
- //Ext重新封裝了response對象
- if(typeof response.getResponseHeader.sessionstatus != 'undefined'){
- //發現請求超時,退出處理代碼...
- }
- }
可以利用的幾個特性:
a)所有的ajax請求均帶有x-requested-with:XMLHttpRequest頭信息
b)Ext.Ajax是單實例對象(非常重要,全局單一Ext.Ajax實例!)
c)註冊Ext.Ajax的requestcomplete事件,每個ajax請求成功後首先響應該事件(概念類似spring的aop攔截)。
對於其他的ajax框架,解決用戶訪問請求超時這個問題的思路是類似的。
在這裏推薦一個很實用的Js方法:
- function getRootWin(){
- var win = window;
- while (win != win.parent){
- win = win.parent;
- }
- return win;
- }
通過該方法,可以在一個任意深度的iframe中調用父iframe中的方法。具體到這裏就是無論哪一個iframe中的用戶訪
問請求超時,都可以通過該方法調用最外層iframe中的退出方法,這樣便爲用戶提供了一個統一的訪問超時退出的UI
呈現。
4)系統異常處理
將實際業務代碼中的各種異常封裝成IOException, ServletException異常,指定過濾器捕獲。其餘處理思路同
用戶訪問超時處理。
5)添加jquery支持
使用jquery順手的且希望在Ext項目中同時使用某些jquery插件的時候,添加jquery支持。
頁面head中直接添加:
- <link rel="stylesheet" type="text/css" href="/js/ext/resources/css/ext-all.css" />
- <script type="text/javascript" src="/js/ext/adapter/jquery/jquery.js"></script>
- <script type="text/javascript" src="/js/jquery.cookie.js"></script>
- <script type="text/javascript" src="/js/ext/adapter/jquery/ext-jquery-adapter.js"></script>
- <script type="text/javascript" src="/js/ext/ext-base.js"></script>
- <script type="text/javascript" src="/js/ext/ext-all.js"></script>
- <script type="text/javascript" src="/js/ext/ext-lang-zh_CN.js"></script>
6)修改佈局
常見的佈局一般是:header,center,footer,以及一個位於頁面左側的tree menu。其實對於Ext的UI實現來說,
去掉header,footer也不錯,因爲Ext的UI本來就做得挺好看再加上去掉header及footer後可以爲center增加不
少可視區面積,一個頁面還可以顯示更多的內容。
應該可以支持這兩種佈局方式的切換,交給用戶選擇。
試了幾次,在border佈局初始化完畢之後再想去掉header,footer區域好像比較麻煩,ext的官方論壇上也說設
計border佈局的本意就是應付靜態呈現。
但是好像已經有javaeye上的同志實現了動態的border佈局呵呵。可以參考一下 EXT2的動態BorderLayout組件 。
7)更換主題
去ext的官網上下載各種主題皮膚 Themes for Ext 2.0
主題皮膚文件拷貝至本地/js/ext/plugins/theme/css/,/js/ext/plugins/theme/images/ 目錄
最好將用戶選擇的主題配置保存在cookie中,這樣用戶每次登陸都可以使用相同的界面主題。
Ext主題切換:
- if($.cookie('ext.theme') != null && $.cookie('ext.theme') != 'default'){
- Ext.util.CSS.swapStyleSheet("theme","/js/ext/plugins/theme/css/"+$.cookie('ext.theme'));
- }
8)添加自定義的toolbar圖標
直接參考javaeye上的這邊文章 共享一些Ext的圖標 即可,作者提供的圖標很好看,使用也非常簡單。
9)生成Excel文檔
最先參考的資料是extjs論壇上面的這篇文章:GridPanel directly to Excel.
作者思路不錯,就是利用javascript直接讀取GridPanel的store數據,然後生成一個描述excel文檔的xml數據,最後
再通過一個包含了該xml數據的"data" URL下載該excel。
該方法的好處是通用性比較強,生成的excel文檔也不難看,並且是不需要服務器端參與處理的一種純客戶端解決方案。
但是最大的缺點是目前IE7不支持(This needs a browser that supports data URLs. FF, Opera and IE8 will support this.)。
而後發現dojochina網站上的一個用戶整理和修改了這個生成excel文檔的實現方法。
1、沒有考慮到含有序號和選擇框的grid,
2、utf8轉換bug.
3、寬度的bug
4、不支持ie6、ie7和Safari
原文地址:官方Grid導出到Excel修正版 (作者給出的代碼有些小問題,需要略微進行些調整)
如果是IE瀏覽器,客戶端將以multipart/form-data方式向服務器端提交該xml數據。
原文給出了後臺由php實現時的exportexcel.php代碼。
如果後臺由java實現,exportexcel.jsp
- <%@page import="java.util.Date"%>
- <%@page import="org.apache.commons.lang.time.DateFormatUtils"%>
- <%@page import="com.oreilly.servlet.multipart.*"%>
- <%
- response.setContentType("application/vnd.ms-excel");
- response.setHeader("Content-disposition","attachment;filename="+
- (DateFormatUtils.format(new Date(),"yyyyMMddHHmmss"))+".xls" );
- MultipartParser parse = new MultipartParser(request,1000000000);
- Part part = null;
- int maxcount = 0;
- ParamPart param = null;
- while(true){
- part = parse.readNextPart();
- if(part == null || maxcount>1000)
- break;
- if(part.isParam() && part.getName().equalsIgnoreCase("exportContent")){
- param = (ParamPart)part;
- break;
- }
- maxcount++;
- }
- if(param!=null){
- response.getWriter().println(param.getStringValue());
- }else{
- ;
- }
- %>
這裏使用 com.oreilly.servlet 解析multipart/form-data類型數據。com.oreilly.servlet 很適合文件,表單混合提
交、多文件上傳的數據解析。
10)js文件管理
凡是這種基於javascript的富客戶端解決方案一大問題就是js文件太多。每個頁面不僅要導入Ext的css,js文件,
還要導入每個頁面應用需要的一些js文件,這樣管理起來很麻煩。
原來的情況,至少要導入:
- <link rel="stylesheet" type="text/css" href="/js/ext/resources/css/ext-all.css" />
- <script type="text/javascript" src="/js/ext/adapter/jquery/jquery.js"></script>
- <script type="text/javascript" src="/js/jquery.cookie.js"></script>
- <script type="text/javascript" src="/js/ext/adapter/jquery/ext-jquery-adapter.js"></script>
- <script type="text/javascript" src="/js/ext/ext-base.js"></script>
- <script type="text/javascript" src="/js/ext/ext-all.js"></script>
- <script type="text/javascript" src="/js/ext/ext-lang-zh_CN.js"></script>
- <script type="text/javascript" src="/js/extajax.js"></script>
- <script type="text/javascript" src="/js/exttheme.js"></script>
推薦使用 JSLoader 管理衆多的js,css文件
1,編寫一個js文件統一管理支持所有公用css,js文件的動態導入
- //添加jquery支持
- JSLoader.loadJavaScript("/js/ext/adapter/jquery/jquery.js");
- JSLoader.loadJavaScript("/js/jquery.cookie.js");
- JSLoader.loadJavaScript("/js/ext/adapter/jquery/ext-jquery-adapter.js");
- //Ext支持
- JSLoader.loadStyleSheet("/js/ext/resources/css/ext-all.css");
- JSLoader.loadJavaScript("/js/ext/ext-base.js");
- JSLoader.loadJavaScript("/js/ext/ext-all.js");
- JSLoader.loadJavaScript("/js/ext/ext-lang-zh_CN.js");
- //加載自定義toolbar圖標css樣式
- JSLoader.loadStyleSheet("/js/ext/plugins/icon/css/ext-extend.css");
- //加載用戶超時,異常處理
- JSLoader.loadJavaScript("/js/extajax.js");
- //主題管理
- JSLoader.loadJavaScript("/js/exttheme.js");
- //Excel導出支持
- JSLoader.loadJavaScript("/js/ext.excel.js");
2,每個頁面只需要引入:
- <script type="text/javascript" src="/js/jsloader.js"></script>
- <script type="text/javascript" src="/js/assets.js"></script>