用ExtJs作前端框架,通常而言,主框架基本都會使用Border佈局。前端
大概佈局就像這個樣子。node
頂部左側通常顯示系統名稱,右側用戶姓名。前端框架
左側是一個手風琴(Accordion),或者其餘的,好比Tree,用以實現導航或功能菜單。app
中間就是主內容了,Tab選項卡的形式,以輕鬆支持多功能,同時可輕鬆切換,如果整個界面只支持最多一個頁面的話,對於一個後臺系統來講,確實不太方便。框架
固然,也能夠多加幾個模塊,如頂部加一個用戶信息及經常使用操做的工具條。ide
=========================分隔線====================================工具
若是隻是簡單的實現這樣的佈局,那麼代碼能夠很簡單。組件化
var vp = Ext.create('Ext.Viewport', { layout: 'border', items: [ { xtype: 'panel', region: 'north', height: 60 }, { xtype: 'panel', region: 'west', width: 200 }, { xtype:'panel', region:'center' } ] });
定義佈局爲border,再定義三個內容塊,分別爲頂部,左側和中間。佈局
在實際項目中,直接這麼簡單的定義各塊內容行嗎?行,沒問題,確定能跑起來。flex
但對於後期代碼閱讀、維護、擴展等,那問題就來了。
爲何?由於各模塊的內容遠不僅這麼簡單,好比左側模塊,簡單一些,可能就是一個Tree空間,甚至更簡單一些,只是幾個固定的項,那麼,負責一些呢。
以此係統來講,左側包含三塊內容:欄目列表、功能菜單、系統設置,這三塊內容內部各包含一個Tree。
若是代碼所有寫在內容的Items裏的話,層層嵌套,最終會致使單個文件過於龐大,難於閱讀及維護。
=========================分隔線====================================
因此,仍是建議以ExtJs官方推薦的方式編寫腳本,就是以定義(Ext.Define)的方式實現各模塊,再經過動態加載按需加載所須要的文件。
且按功能分類的將腳本寫在不一樣的文件中,能夠看下此係統的全部js文件:
Common:存放在些比較通用的東西,好比數據的Model,一些工具方法等;
Function:對應左側模塊的功能菜單,全部功能菜單裏的功能都放在這;
Main:主框架文件夾,圖片上有幾個是沒用的,暫時還沒刪。Center是中間主內容,LeftPanel是左側模塊,LeftTree是欄目樹,SysSetTree是功能菜單樹及洗頭系統設置樹。
Show:前端流量數據展現的一些功能;
Sys:系統設置相關功能文件。
=========================分隔線====================================
好了,說說主框架的搭建吧。
Ext.define("Yiqi.Main.Main", { extend: 'Ext.container.Viewport', requires: ['Yiqi.Main.Center', 'Yiqi.Main.LeftPanel', 'Yiqi.Common.Tools'], initComponent: function () { this.buildTop(); this.buildLeft(); this.buildCenter(); Ext.apply(this, { layout: 'border', items: [ this.topPart, this.leftPart, this.centerPart ] }); this.callParent(arguments); }, buildTop: function () { // 頭部 this.topPart = Ext.create('Ext.panel.Panel', { region: 'north', margin: '5 5 0 5', header: false, split: true, collapsible: true, collapseMode: 'mini', hideCollapseTool: true, contentEl: 'top_box', height: 45 }); }, buildLeft: function () { //左側菜單 this.leftPart = Ext.create('Yiqi.Main.LeftPanel', { region: 'west', //flex:1, title: '功能菜單' }); }, buildCenter: function () { //主體內容 this.centerPart = Ext.create('Yiqi.Main.Center', { region: 'center' //flex:4 }); } });
Ext.define的方式,定義整個主框架。內部各模塊組件化,這樣代碼看上去,簡潔多了。
=========================分隔線====================================
由於我須要自定義功能菜單是以Tab選項卡的形式打開仍是彈出window的形式打開,因此,整個主框架,也就這一塊花了點心思。
先看下功能菜單是怎麼樣的。
功能地址,就是功能所在的文件路徑&文件名,也是模塊的類名。
瞭解ExtJs動態加載的應該知道這個。
好比:用戶管理,它的功能地址是Yiqi.Sys.Security.UserList,Yiqi是定義的動態加載根路徑,
因此,這塊功能的JS文件路徑實際是:\Sys\Security\UserList.js。
功能類的定義:
Ext.define('Yiqi.Sys.Security.UserList',{ extend:'xxxxxx', //.............TODO });
這也是使用ExtJs的一大好處,功能菜單,能夠隨意的定義功能地址、打開方式等等,而不須要改任何代碼,固然,你得先把功能作好。
而打開方式的實現過程,也比較簡單,定義樹中node的單擊事件,判斷單擊的node,有無定義功能地址,若是有,再判斷打開方式,若是是彈出窗,則以window的形式打開;若是是選項卡,則以選項卡的方式打開。
onItemClick: function (view, rec, item, idx, e) { var path = rec.get("LoadPath"); //--功能地址 var openType = rec.get("OpenType"); //--打開方式 var me = this; if (!Ext.Object.isEmpty(path) && !Ext.Object.isEmpty(openType)) {if (openType == "window") { var win_id = 'syswin_' + rec.get("id"); var win = Ext.WindowManager.get(win_id); if (win) { Ext.WindowManager.bringToFront(win); } else { win = Ext.create(path, { title: rec.get("text"), iconCls: rec.get("iconCls"), id: win_id }); win.show(); } } else if (openType == "tab") { //--選項卡方式打開,先判斷當前功能是否已經打開,若是已打開,則無需新建,直接將該功能設爲活動選項卡就好了。 //--me.ownerCt.ownerCt.centerPart是主框架的中間內容模塊。 var tab = me.ownerCt.ownerCt.centerPart.getComponent('tab_sys_' + rec.get('id')); if (!tab) { var newitem = Ext.create(path, {}); tab = Ext.create('Ext.panel.Panel', { title: rec.get('text'), itemId: 'tab_sys_' + rec.get('id'), layout: 'fit', closable: true, iconCls: rec.get('iconCls') || 'icon_preview', items: newitem }); me.ownerCt.ownerCt.centerPart.add(tab); } //--設爲活動選項卡 me.ownerCt.ownerCt.centerPart.setActiveTab(tab); } } }
至此,主框架就差很少了~~~