抱歉,最近比較忙,更新的比較慢~html
=========================分隔線====================================app
流量系統,是開放給內部全部用戶使用,用於查詢網站相關流量數據。ide
Boss們須要能看到全部欄目的全部流量數據,而普通編輯們,則只能查看本身負責欄目的流量數據;工具
管理員須要給全部人設置權限的權限;網站
。。。。。。ui
對於普通的Web應用程序或MVC來講,能夠經過控制html元素的顯示與否、可用與否來實現權限。this
而對於ExtJs來講,如何實現就是另外一回事了。url
=========================分隔線====================================spa
先來看看有哪些地方須要配置權限吧。code
左邊手風琴有三個部分,Accordion控件不像Tree同樣,能夠從服務端加載數據生成控件,它只能手動的逐個添加子項。
因此要實現權限控制,只好從服務端加載完權限信息後,再來控制各部分顯示與否。
另外,若是手風琴的子項內,也就是內部的Tree控件,沒有任何節點的話,則自動將該子項隱藏。
Ext.define('Yiqi.Main.SysSetTree', { extend: 'Ext.tree.Panel', requires: ['Yiqi.Common.Model.FunctionMenu'], parentId: 2, loadUrl: '', initComponent: function () { this.loadMask = new Ext.LoadMask(this, { msg: '加載中...' }); this.buildStore(); var me = this; Ext.apply(this, { rootVisible: false, lines: false, store: this.dataStore, listeners: { itemclick: this.onItemClick, beforeitemexpand: function () { me.loadMask.show(); }, itemexpand: function () { me.loadMask.hide(); }, load: function (store, obj, records, eOpts) { if (!me.loadMask.isHidden()) { me.loadMask.hide(); } if (records.length <= 0) { me.ownerCt.remove(me);//--若是沒有子項,則隱藏 } } } }); this.callParent(arguments); } });
各部分裏邊的內容,都是Tree控件,這個不用多說也能想到,直接在服務端返回可用的就行。
權限配置功能也比較簡單。
=========================分隔線====================================
左側手風琴比較簡單。
而下邊這個,就比較麻煩了。
這是哪?這是流量數據顯示界面頂部的工具條(Toolbar),用於切換數據顯示。
是的,並不是全部欄目的功能都同樣。
好比:某些欄目纔有地理信息統計,某些欄目纔有訪問排行。。。。。。
若是在左側加一個Tree控件來顯示全部功能的話,那麼就簡單多了,對吧。
但這樣的話,就嚴重擠壓了圖表的空間,對於這樣一個系統,圖表及數據的展現,纔是重點。
而在頂部以一個工具條的方式顯示菜單的話,彷佛就簡潔多了。。。
好吧,那就這麼幹吧。。。
=========================分隔線====================================
通常Toolbar都是固定的,而基於服務端數據的Toolbar則是靈活的。
對Toolbar子組件的類型,有三種要求:
一、純分組用,就像文件夾同樣;
二、帶功能的分組,即有子組件的按鈕,在ExtJs裏,叫SplitButton。
三、就是純按鈕了。
先看一下用來加載Toolbar的數據是什麼樣的。
功能地址:就是點擊按鈕後,會加載的功能地址,也是功能對應的js文件路徑。這個在以前的文章裏也說過。
能夠看到,有些項目的功能地址是空的,沒錯,就是用這個字段來區別類型。
有子項目,功能地址爲空,則說明是純分組用的;有子項目,功能地址也不爲空,則說明是帶分組的功能按鈕;沒有子項目的就是純按鈕咯。
=========================分隔線====================================
從服務端加載好這些數據後,逐一循環,根據這個規則來決定ExtJs須要建立的類型,建立完成,再add到Toolbar裏。
固然,理論上支持無限級子菜單。
Ext.define('Yiqi.Show.Catagory.FunctionToolBar', { extend: 'Ext.toolbar.Toolbar', alias: 'widget.functionbar', catagoryId: 1, loadStatics: function (path, scope) { }, handlerScope: null, initComponent: function () { Ext.apply(this, { items: [ //--一加載就顯示Loading,提升用戶體驗 { xtype: 'displayfield', value: '<img src="/Scripts/ext4.2/resources/themes/images/default/grid/loading.gif"/> 菜單加載中......' } ] }); this.callParent(arguments); }, afterRender: function () { //--渲染完成後,再從服務端加載數據,並建立Toolbar this.loadEnabledMenu(); this.callParent(arguments); }, loadEnabledMenu: function () { var me = this; Ext.Ajax.request({ url: '/FunctionMenu/GetEnabledList', params: { catagoryId: me.catagoryId }, method: 'POST', success: function (response, opts) { Yiqi.Common.Tools.IsLogin(response); var result = Ext.decode(response.responseText); var menu = me.buildMenu(result); me.removeAll(true); me.add(menu); }, failure: function (response, opts) { Ext.Msg.alert("提示", "保存失敗(報錯)~!"); } }); }, buildMenu: function (list) { var me = this; var menu = []; //--循環全部 Ext.Array.each(list, function (m) { menu.push(me.createSingle(m)); }); return menu; }, createSingle: function (data) { var me = this; var menu = {}; //--功能地址不爲空 if (!Ext.isEmpty(data.LoadPath, true) && Ext.String.trim(data.LoadPath).length > 0) { if (data.Children.length > 0) { menu.xtype = 'splitbutton'; } if (me.handlerScope) { menu.scope = me.handlerScope; } menu.handler = function () { this.createItem(data.LoadPath, menu); //me.loadStatics(data.LoadPath, menu); } } menu.text = data.text; menu.iconCls = data.iconCls; //--有子菜單,則繼續循環 if (data.Children.length > 0) { var childMenu = me.buildMenu(data.Children); menu.menu = { items: childMenu }; } return menu; } });