jhope代碼分析以及網站結構

如下圖所示,為Extjs部分代碼提供的網頁結構:
_
網站看上去本來是這樣的
_
前端采用ExtJS,與后臺的SpringMVC+Spring+Hibernate進行數據交互。
之前分析過登錄的過程,不贅述
在loginController處理登錄返回結果的最后,如下語句
_
也就是如果正確登錄的話,跳轉到xtype為appcentral的頁面
_
這是一個普通的panel
_
它的內容是經典的四分空間
如果仔細看代碼,會看到就是我們這片博文最開始的那個示意圖所示的分割方式。
這里面我們重點看看“菜單”那個空間,也就是left
網頁中,菜單的形式是這樣的
_
下拉框的樣子,挺復雜
但是點擊最左側的小三角,也可以變換形式:
_
_
看到至少有兩種其他表現形式
下面看看ExtJS的代碼是如何獲取菜單內容的:
Central.js這個View帶有一個ViewController
_
名為CentralController.js
這個View還帶有一個ViewModel
_
名為CentralModel.js,樣子如下
_
在它的constructor方法中
_
EU.RS();方法是作者自己定義的js方法。
發送給SpringMVC
_
_
看到buildListToTree()方法是static的,因此可以直接使用,沒有什么依賴注入之類的。
也不能這么說,注入了一個一成不變的參數
_
_

@Service
public class SystemFrameService {@Resourceprivate DaoImpl dao;@SystemLogs("獲取系統左側樹形菜單")public List<TreeNode> getMenuTree() {String userid = Local.getUserid();String usertype = Local.getUserBean().getUsertype();String companyid = Local.getCompanyid();String sql = "select" + "     a.menuid,a.menuname as text,a.parentid as parentId,a.icon,a.iconCls,a.iconColor, "+ "     c.moduletype as type,c.modulesource as url,c.objectid,a.menutype,a.orderno,a.isexpand as expanded "+ " from" + "      f_companymenu a,f_companymodule b,f_module c " + " where a.companyid = b.companyid "+ "      and a.cmoduleid = b.cmoduleid " + "      and b.moduleid = c.moduleid "+ "      and a.companyid = '" + companyid + "' ";if (!usertype.equals("01")) {sql += " and (" + "        (" + "           select count(1) c "+ "              from f_modulefunction mf1,f_userfunctionlimit ufl "+ "              where mf1.cmoduleid = b.cmoduleid and mf1.functionid = ufl.functionid and ufl.userid = '"+ userid + "' " + "        ) > 0" + "     or " + "     ( " + "           select count(1) c "+ "              from f_modulefunction mf2,f_rolefunctionlimit rfl,f_userrole ur "+ "              where mf2.cmoduleid = b.cmoduleid and mf2.functionid = rfl.functionid and rfl.roleid = ur.roleid and ur.userid ='"+ userid + "' " + "        ) > 0" + " ) ";}sql += " order by a.orderno";List<TreeNode> dataList = dao.executeSQLQuery(sql, TreeNode.class);Map<String, TreeNode> parentMap = new HashMap<String, TreeNode>();for (TreeNode node : dataList) {if (!CommonUtils.isEmpty(node.getParentId())) {parentNode(parentMap, node);}}for (String key : parentMap.keySet()) {dataList.add(parentMap.get(key));}return dataList;}
}

這部分獲取參數的代碼還是比較壯觀的,執行了sql而非hql語句,返回值是自定義類型。
上述sql語句中直接使用了數據庫中數據表的名字和字段,我們補充一下對應的信息:
_
_
_
其實在phpmyadmin中只能看到字段的含義,數據表的內容,是無法直觀用圖形的方式看到不同數據表之間關系的。推薦使用powerdesigner讀取mysql導出的sql文件,形成pdm圖,可以方便的看到數據庫各種關系的全貌,直觀而且準確。
_

_
使用powerdesigner生成pdm圖的過程,可以參考
http://blog.csdn.net/duanchangqing90/article/details/38089557
這篇文章

使用chrome瀏覽器看看http request的內容以及response的內容
_
Request URL:http://www.jhopesoft.com:8080/cfcmms/platform/systemframe/getmenutree.do
_
_
也就是說,前端和后臺的通訊完全在意料之中。
回到ExtJS代碼中Central.js的ViewModel文件
_
上述文件只是初始化,為js中的變量menus賦值
這些數據,如何使用呢?
_
上圖為菜單的View文件
_
_
_
這些數據從后臺返回,并處理,然后存放在js變量中,賦值給store
_
_
看來我對于filterer的猜測是錯的
下面看看TreeStore的root屬性(config)
_
對于Ext.data.TreeStore來說,root屬性中的expanded屬性設置為true,意味著不管這個store是否設置為autoLoad,整個store都會直接load。
寫到這里,我們還是沒有搞清楚Component和Store之間是什么關系,為什么這些數據可以被顯示成View中菜單的樣子。
我們來看看Ext官網上 Ext.data.TreeStore 的案例代碼:

//Store部分的代碼
var store = Ext.create('Ext.data.TreeStore', {root: {expanded: true,children: [{ text: 'detention', leaf: true },{ text: 'homework', expanded: true, children: [{ text: 'book report', leaf: true },{ text: 'algebra', leaf: true}] },{ text: 'buy lottery tickets', leaf: true }]}
});//View部分的代碼
Ext.create('Ext.tree.Panel', {title: 'Simple Tree',width: 200,height: 500,store: store,rootVisible: false,renderTo: Ext.getBody()
});

上述代碼的效果圖如下
_
也就是說一個View和一個Store就可以輕易創建出上述樣子的菜單。
我們也看到treepanel沒什么代碼,store的核心就是root children 和 text。
_
很顯然c必須是字符串的數組也就是

c = [{text:菜單項1},{text:菜單項2},{text:菜單項3}]

那么菜單上面的文字,必須出現在text這個屬性中,如下圖
_
我們看看c的來源
_
就是Ext采用Ajax()方法對某個url發送request的返回值
因此我們有必要先去瀏覽器的開發者工具看看,返回值究竟是怎樣的形式:
_
也就是說,ajax發送的返回值,在被ExtJS的js代碼處理之前,就已經有了text這個字段,那么就肯定是Spring代碼的自定義返回值,就已經安排好的。
_
_
上述的POJO是自定義返回值,其中一個字段就是text
而執行查詢的executeSQLQuery()方法,也是DAO中自定義返回值的查詢方法(非自定義返回值意味著,采用PO作為返回類型)
上面的描述基本講清楚了,菜單上面的中文字符串的來源。

下面看看菜單上的菜單項,點擊以后,有什么效果。
菜單的View部分頁面的本質是Ext.tree.Panel
_

_

_
上述js代碼就是,你點擊菜單上的文字后,將一個完全新的tab頁,并列到“首頁”tab右邊的js代碼

                    /*** 將標準模塊加入tabpanel中了,如果已經有了,就轉至該tab頁 itemId:module_(moduleName)*/addModuleToMainRegion : function(menuitem, donotActive) {var moduleName = menuitem.moduleName;var menuid = menuitem.menuid;var view = this.getView().down('maincenter');var tabItemId = 'module_' + menuid; // tabPanel中的itemIdvar tab = view.down('> panel#' + tabItemId);// 查找當前主區域中是否已經加入了此模塊了if (!tab) {var tabPanel = null;// type : 01=外部xtype,03=實體對象if (menuitem.type == '01') {tabPanel = Ext.getCmp(tabItemId);if (!tabPanel) {tabPanel = Ext.create(menuitem.url, {id : tabItemId,autoDestroy : true,title : menuitem.text,closable : true});}} else if (menuitem.type == '03') {tabPanel = modules.getModuleInfo(moduleName).getModulePanel(tabItemId);}if (!tabPanel)return;if (!Ext.isEmpty(menuitem.glyph))tabPanel.glyph = menuitem.glyph;if (!Ext.isEmpty(menuitem.iconCls))tabPanel.iconCls = menuitem.iconCls;tab = view.add(tabPanel);}if (!donotActive)view.setActiveTab(tab);}

這段代碼應該好好學學
_

_
上圖中item
_
其實寫到這里我的感覺就是強弩之末。
你點擊了菜單的某一個選項,你想知道都發生了什么。

其實你很清楚,不論點擊那個菜單項,結果是一樣的:在首頁tab右邊,生成一個新的tab,至于這個tab是什么結構,里面是什么內容,取決于菜單項的id之類的信息。也就是剛剛進入網站,默認load那個treePanel,也就是菜單。(菜單是個treePanel,剛進入網站的時候默認發送ajax類型的request獲取了菜單的所有內容)

那么,點擊了菜單項以后,究竟發生了什么呢?

我們之前分享的那段代碼,有一段十分重要:

//定位到maincenter
var view = this.getView().down('maincenter');
...................
//創建tabelse if (menuitem.type == '03') {tabPanel = modules.getModuleInfo(moduleName).getModulePanel(tabItemId);}......................//把tab加到view上,也就是讓它顯示tab = view.add(tabPanel);

上述代碼的核心就是modules
_

/*** 取得模塊的定義* @param {} moduleid ,參數可以是moduleid、modulecode、objectname、objectid* @return {}*/getModuleInfo : function(moduleid){if (Ext.isEmpty(moduleid)) {EU.toastWarn('加載moduleid不能為空!');return;}var me = this,result = me.modules.get(me.modulesKeys[moduleid.toUpperCase()]);if (result) return result;var url = "platform/module/getmoduleinfo.do",params = {moduleid : moduleid};EU.RS({url : url,params : params,async : false,callback : function(moduleinfo){me.replaceRef(moduleinfo, moduleinfo);if (moduleinfo) {result = new Ext.create('app.view.platform.module.ModuleInfo', moduleinfo);me.modules.add(moduleinfo.moduleid, result);me.modulesKeys[moduleinfo.moduleid.toUpperCase()] = moduleinfo.moduleid;me.modulesKeys[moduleinfo.modulecode.toUpperCase()] = moduleinfo.moduleid;me.modulesKeys[moduleinfo.fDataobject.objectid.toUpperCase()] = moduleinfo.moduleid;me.modulesKeys[moduleinfo.fDataobject.objectname.toUpperCase()] = moduleinfo.moduleid;} else {EU.toastWarn('加載' + moduleid + '的模塊數據時失敗!');}}});return result;},

_
Ctrl + H 搜索一下
modulepanel 意味著:
_
同志們,我們找到所有的核心了!!!
Module.js這個文件太關鍵了,因為它就是模板,這個文件就是個普通panel但是這個文件中,定義了Store和Items
也就是說,你點擊菜單項創建的新的tab,取哪些數據,顯示哪些UI就完全取決于這個文件了~!!!
我們上代碼:

initComponent : function(){var me = this;if (Ext.isObject(me.param)) Ext.apply(me, me.param)me.moduleInfo = modules.getModuleInfo(me.moduleId);me.objectName = me.moduleInfo.fDataobject.objectname;me.model = me.moduleInfo.model;me.istreemodel = me.moduleInfo.fDataobject.istreemodel;//Store是那種類型:二選一me.store =Ext.create('app.view.platform.module.' + (me.istreemodel ? 'treegrid.TreeGridStore' : 'grid.GridStore'), {module : me.moduleInfo,modulePanel : me,model : me.model});me.store.getProxy().extraParams.moduleName = me.moduleInfo.fDataobject.objectname;if (me.parentFilter) me.store.parentFilter = me.parentFilter;me.enableNavigate =!me.istreemodel && me.enableNavigate&& (me.moduleInfo.fDataobject.navigatedesign || me.moduleInfo.getNavigateSchemeCount() > 0);me.collapseNavigate = me.moduleInfo.getNavigateSchemeCount() == 0 || me.collapseNavigate;me.defaults = {moduleInfo : me.moduleInfo,objectName : me.objectName,modulePanel : me,parentFilter : me.parentFilter};//Items中的核心UI Componentvar center = {xtype : me.istreemodel ? 'moduletreegrid' : 'modulegrid',store : me.store,region : 'center',modulePanel : me,inWindow : me.inWindow};me.items = [me.centerRegionNest ? {xtype : 'panel',region : 'center',layout : 'fit',items : [Ext.apply(center, me.defaults)]} : center];

寫到這里真的寫不下去了,因為,你為什么這么傻呢?
讀代碼多枯燥啊,我們直接去chrome上看數據傳遞,不就很直觀么?走著!
_
我們看到執行了三次request
_
getmoduleinfo.do
fetchdata.do
這明顯就是發送給SpringMVC的
如果看看response中的數據:
getmoduleinfo.do
_
fetchdata.do
_
看上去上面兩類request分別用來獲取
整個模板的數據和數據庫中對應數據的數據。
_
fetchdata.do在整個代碼中,只出現一次,靠,復用啊
_
我們看到了一個經典的Store,看到了吧,完美

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/278570.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/278570.shtml
英文地址,請注明出處:http://en.pswp.cn/news/278570.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu下Authentication token manipulation error或者Authentication Failure解決辦法

在Ubuntu18.04使用以下命令出現以下錯誤: 用passwd為新建用戶或者root添加密碼:Authentication token manipulation error 切換root用戶出現Authentication Failure. 網上出現了大致兩種方法: 第一種&#xff1a;用戶文件和密碼文件被保護&#xff0c;用chattr命令移除保護即可…

初學者:如何使用虛擬PC將Windows 7安裝到虛擬機

Continuing in our series covering how to use Virtual PC, this week we’ll be showing you how to install Windows 7 into a virtual machine. It’s a very simple process, but here’s the step-by-step guide for beginners. 繼續我們的系列文章&#xff0c;介紹如何使…

arcgis本地服務快速遷移到新機

情景 在本機或服務器發布了幾十、幾百個gis服務&#xff0c;當換電腦或者換服務器時不可能挨個找源文件重新發布服務&#xff0c;于是就想著既然是本地文件&#xff0c;一定可以拷貝過去的&#xff0c;經過一番搜索&#xff0c;結果如下: 方案一、遷移至新站點 新機站點創建…

js中 給json對象添加屬性和json數組添加元素

json對象&#xff1a; 比如現在有一個json對象為jsonObj&#xff0c;需要給這個對象添加新的屬性newParam&#xff0c;同時給newParam賦值為pre。做法如下&#xff1a; var jsonObj{param1:22,param2 :33}; 現在給jsonObj添加一個新的屬性newParam jsonObj.newParam pre; 新的…

zabbix中php信息缺失之后的安裝

安裝php下enable bcmath和gettext &#xff08;在安裝php時可以添加 --enable-bcmath --enable-gettext&#xff09;1,bcmath安裝方法bcmath這個擴展在php源安裝包壓縮包中都是有的&#xff0c;需要重新編譯一下才能夠支持&#xff1b;cd php-5.2.7/ext/bcmath&#xff08;源…

極客大佬用什么電腦_極客特惠:筆記本電腦,高清電視和免費應用

極客大佬用什么電腦If you love new gear but not high prices then we’ve got some deals for you; grab some deeply discounted laptops, monitors and HDTVs, and free mobile apps in this week’s Geek Deals roundup. 如果您喜歡新設備&#xff0c;但不喜歡高價&#x…

Linux內核 TCP/IP、Socket參數調優

詳見http://blog.csdn.net/u010009038/article/details/51917460轉載于:https://blog.51cto.com/jack88/2063979

ppt插入html(用office而不是wps)

最近新get到的技能&#xff0c;在ppt里面插入html&#xff01;注意要用 Microsoft Office PowerPoint 才行&#xff0c;而不是wps&#xff0c;一定要先安裝Microsoft Office PowerPoint再執行以下操作。 1、修改注冊表的值&#xff0c;才能在PowerPoint中插入 Microsoft Web B…

如何使用SkyDrive的25 GB作為映射驅動器以方便訪問

SkyDrive is an online storage system included in Windows Live, which gives you 25 GB of space that you can sync to your desktop. Here’s how to connect it to your Windows 7 computer as a mapped drive. SkyDrive是Windows Live中包含的一個在線存儲系統&#xff…

SpringBoot+Mybatis 框架之 @SelectProvider注解方式搭建

之前搭建了Select標簽來做SringBootMybatis的集成。這次使用SelectProvider標簽的方式搭建一次。 一、搭建SpringBoot的項目 https://start.spring.io/自己配置SpringBoot的項目&#xff0c;點擊“Generate Project”按鈕就可以下載下來一個配置好的SpringBoot項目。 二、項目結…

程鑫峰:1.23日央行推行負利率政策,倫敦金后市行情解析

程鑫峰&#xff1a;1.23日央行推行負利率政策&#xff0c;倫敦金后市行情解析 QQ截圖20180123153028.png ??盡管美國政府關門鬧劇剛剛結束&#xff0c;但交易員、投資者和策略師對于美元的前景依然不太樂觀。美國貨幣政策對美元的影響力減弱可能是全球通貨再膨脹交易的另一個…

從購買域名到nginx,flask搭建自己的網站

搭建一個只屬于自己的網站? 一、注冊域名&#xff08;可選*&#xff09; 1.注冊阿里云賬號 網址&#xff1a;登錄&#xff08;注冊&#xff09; 2.購買域名&#xff1a;阿里云域名注冊 有一元域名、免費域名等。 購買過程中需要創建信息模板&#xff08;必須完成郵箱真實…

alexa語音實現_如何通過語音刪除Alexa錄音

alexa語音實現Amazon亞馬孫Amazon is rolling out new privacy features today for Alexa. In addition to an educational “privacy hub,” the company lets you delete your stored recordings by voice. But it’s off by default; you’ll need to flip a switch. 亞馬遜…

linux如何查看所有的用戶(user)、用戶組(group)、密碼(password/passwd)

linux如何查看所有的用戶和組信息_百度經驗https://jingyan.baidu.com/article/a681b0de159b093b184346a7.html linux添加用戶、用戶組、密碼_百度經驗https://jingyan.baidu.com/article/335530da8b7e0419cb41c3e5.html 給用戶開通sudo權限 xxx is not in the sudoers file.Th…

angular之兩種路由

安裝angular npm install -g angular/cli ng new myapp ng g component componentName 自帶路由 引入&#xff1a;angular-route.js <div ng-controllerctr1><a href#home>首頁</a> <a href#mine>我的</a> <div ng-view></div><d…

用scrapy框架寫爬蟲

爬蟲可以發送給引擎的兩種請求&#xff1a; # 1、url&#xff1a;# &#xff08;爬蟲&#xff09;yield scrapy.Request -> 引擎 -> 調度器&#xff08;發送給調度器入隊&#xff09; -> 引擎&#xff08;調度器出隊請求于引擎&#xff09;# -> 下載器&#xff08;…

audacity_如何在Audacity中快速編輯多個文件

audacityGot a bunch of files that need to be edited the same way? You can automate the process to save time and effort using Audacity’s Chain feature and modify tons of files at the same time. 有一堆需要以相同方式編輯的文件&#xff1f; 您可以使用Audacity…

通過api管理grafana

1. 生成api key 參考&#xff1a; http://docs.grafana.org/http_api/auth/ 2.點擊添加后&#xff0c;生成了個獲取一個deshboards的api樣例 3.放到linux上運行測試&#xff0c;結果成功返回。 4. 有些api并不支持使用api key 來連接&#xff0c;如下圖中的搜索用戶接口&#x…

NFS服務的配置過程

NFS服務的配置過程服務端:1)安裝nfs和rcp服務yum install nfs-utils rpcbind -y 因為NFS支持的功能多,不同的功能會使用不同的程序來啟動每啟動一個功能就會啟動一些端口來傳輸數據,默認NFS讀完啟動會產生多個進程,多個端口號信息,會隨機使用未被使用的端口重啟又會變化,所以…

vue項目將token存在(vuex)store和localstorage中

文章目錄一、準備工作和token1、準備工作2、介紹token用法二、創建storage&#xff0c;store&#xff0c;request1、src目錄&#xff1a;2、封裝storage&#xff08;可選&#xff09;3、創建store4、創建request三、配置代理&#xff0c;封裝路由router、設置路由守衛&#xff…