http://developer.51cto.com/developer/51cto-salon-13/
![]() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
張昊J-Hi(http://www.j-hi.net) |
2011年5月8日 # http://developer.51cto.com/developer/51cto-salon-13/
描述:在DWZ版中lookup的處理機(jī)制與經(jīng)典的完全不同,對于lookup有兩種展現(xiàn)形式,一種是通過點(diǎn)擊lookup圖標(biāo)彈出對話框后帶回選中的值,另一種是通過在文本框中輸入相應(yīng)信息從而實(shí)現(xiàn)聯(lián)機(jī)式的查找?guī)Щ匦Ч膶?shí)現(xiàn)目的來看,無非是讓lookup的實(shí)體的主鍵值帶回到hidden的一個(gè)元素中,而其它值只是作為顯示參考之用,與底層的數(shù)據(jù)庫結(jié)構(gòu)與數(shù)據(jù)庫表無關(guān)。一個(gè)完整的lookup由如下html元素構(gòu)成:1)一個(gè)hidden用于保存帶回實(shí)體主鍵的ID值;如果要實(shí)現(xiàn)缺省的lookup過濾或排序可以相應(yīng)的pageInfo的hidden元素,具體實(shí)現(xiàn)方式的用例參見《HowTo手冊》;2)n個(gè)text用于顯示帶回的多個(gè)數(shù)據(jù)帶回項(xiàng)(注意:因?yàn)閹Щ氐臄?shù)據(jù)項(xiàng)與數(shù)據(jù)訪問層也就是數(shù)據(jù)庫表無關(guān),因此每個(gè)text的name都有一個(gè)hi_作為前綴);3)一個(gè)lookup有且只有一個(gè)主帶回項(xiàng),只有主帶回項(xiàng)的文本框是可編輯的并且只有主帶回項(xiàng)會有lookup圖標(biāo)也就是html的中的a元素。
場景描述:一個(gè)會員編輯頁面要指定該會員所在的省份、城市、地區(qū),要求在選擇省份后會自動過濾該省份的城市,地區(qū)以此類推。 以下所有步驟只是修改OrganizationEdit.jsp文件,即可 步驟一、為省份的主帶回項(xiàng)加callback回調(diào)方法,并在實(shí)現(xiàn)該js方法 <input type="text" class="textInput" name="organization.hi_province.name" value="${organization.province.name}" callback="processProvince" function processProvince(json){ document.getElementById("pageInfo.province.f_id").value = json.id; } //該方法的目的是在選擇某個(gè)省份后將該省份的ID值放到指定的hidden元素中 步驟二、為城市加一個(gè)用于過濾的hidden元素,注意:processProvince()方法中的賦值語句就是該hidden元素;用于過濾的name必須與PageInfo的具體類相對應(yīng);必須要指定lookupGroup與lookupName <input type="hidden" lookupGroup="organization" lookupName="city" name="pageInfo.province.f_id" id="pageInfo.province.f_id" value=""/> 步驟三、為城市的主帶回項(xiàng)加callback回調(diào)方法,并在實(shí)現(xiàn)該js方法 <input type="text" class="textInput" name="organization.hi_city.name" value="${organization.city.name}" callback="processCity" function processCity(json){ document.getElementById("pageInfo.city.f_id").value = json.id; } 步驟四、為地區(qū)加一個(gè)用于過濾的hidden元素 <input type="hidden" name="pageInfo.city.f_id" id="pageInfo.city.f_id" lookupGroup="organization" lookupName="region" value=""/> 總結(jié):級聯(lián)下拉實(shí)際上是lookup的一個(gè)變種形式,主要的思想是為你要級聯(lián)的下拉的lookup加入過濾項(xiàng),例如在城市加一個(gè)省份的過濾項(xiàng),在選擇省份時(shí)后,會通過回調(diào)方法將這個(gè)過濾項(xiàng)的值存到該過濾項(xiàng)中。這樣逐級過濾就實(shí)現(xiàn)了級聯(lián)下拉的效果. 大家可以簡單將J-Hi建模工具理解為數(shù)據(jù)庫的E-R圖,每個(gè)實(shí)體就對應(yīng)一個(gè)數(shù)據(jù)庫的表,而實(shí)體中每個(gè)屬性就對應(yīng)數(shù)據(jù)庫表的一個(gè)字段。那么實(shí)體與實(shí)體之間的關(guān)系或表與表的關(guān)系又是如何描述的呢? 對于數(shù)據(jù)庫表的關(guān)系大體可分為,如下幾種形式 many-to-one:相當(dāng)于一個(gè)數(shù)據(jù)庫表的字段(外鍵)對應(yīng)另一張數(shù)據(jù)庫表的主鍵,對于J-Hi來說,就是一個(gè)lookup(查找?guī)Щ兀<匆粋€(gè)實(shí)體中的某個(gè)屬性是lookup類型,這個(gè)屬性會lookup另一個(gè)實(shí)體。對lookup定義的操作步驟請參見“應(yīng)用開發(fā)視頻”。頁面中的展示形式,例如你有一個(gè)報(bào)銷單,要lookup用戶,那么平臺就會自動將用戶的名稱帶回來,并在數(shù)據(jù)庫中將用戶的ID值保存到報(bào)銷單表的相應(yīng)字段中。
one-to-many:相當(dāng)于一個(gè)數(shù)據(jù)庫表下面會有一個(gè)或多個(gè)明細(xì)表,例如一個(gè)報(bào)銷單是主表而報(bào)銷單明細(xì)是明細(xì)表。在數(shù)據(jù)庫端的實(shí)現(xiàn)形式為,在明細(xì)表中有一個(gè)主表的外鍵ID字段。在J-Hi中我們稱之為引用,具體操作見聯(lián)機(jī)幫助
one-to-one:所謂一對一的關(guān)系在數(shù)據(jù)庫上的理解為,B表每加一條記錄A表也會隨著增加一條記錄,在J-Hi中的表現(xiàn)形式為實(shí)體繼承 對于實(shí)體的繼承,不只是簡單的表one-to-one關(guān)系,實(shí)體的繼承還包括所有的java類的繼承關(guān)系,JSP頁面的整合等等
many-to-many:多對多是一種復(fù)雜的表關(guān)系,J-Hi是通過中間過渡表來實(shí)現(xiàn)這種多對多的關(guān)系,例如一個(gè)項(xiàng)目可以有多個(gè)成員,而一個(gè)成員又有可能在多個(gè)項(xiàng)目中,建模的圖為 1.前臺頁面: //自定義一個(gè)回調(diào)函數(shù)ajaxDone <form action="expert_BaseInformationSave.action?navTabId=expert_BaseInformationList&callbackType=closeCurrent&ajax=1" method="post" class="pageForm required-validate" onsubmit="return validateCallback(this, ajaxDone)">
//回調(diào)函數(shù) <script type="text/javascript"> function ajaxDone(json) { alert(json.expert.name); } </script>
2.后臺代碼: public class Expert_BaseInformationSaveAction extends BaseAction implements SynchronizationData{ private Expert_BaseInformation expert_BaseInformation; private JSONObject json;
public String execute() throws Exception { Expert_BaseInformationManager expert_BaseInformationMgr = (Expert_BaseInformationManager) SpringContextHolder.getBean(Expert_BaseInformation.class); if(super.perExecute(expert_BaseInformation)!= null) return returnCommand(); expert_BaseInformationMgr.saveExpert_BaseInformation(expert_BaseInformation); super.postExecute(expert_BaseInformation); json = new JSONObject("expert", expert_BaseInformation, "name, gender, unit");
return "json"; }
public Expert_BaseInformation getExpert_BaseInformation() { return expert_BaseInformation; }
public void setExpert_BaseInformation(Expert_BaseInformation expert_BaseInformation) { this.expert_BaseInformation = expert_BaseInformation; }
public JSONObject getJson() { return json; } }
注意:action中必須定義public JSONObject getJson() { return json; }, 否則前臺無法獲取json數(shù)據(jù)。 注:該文檔由J-Hi愛好者"笨笨"提供,他的QQ號為289542213,歡迎大家與他在技術(shù)上多多交流 本文主要講解J-hi中樹的過濾。以員工部門樹為例。 要求在點(diǎn)擊某個(gè)員工時(shí),能夠查看到該員工所在的部門。
![]()
圖1-部門樹 下圖2是所有員工列表: 圖-2 當(dāng)點(diǎn)擊王五時(shí),顯示王五所在的部門結(jié)構(gòu)樹如圖3。 圖-3 主要代碼部分: 1、Jsp超鏈接代碼: <a href="tree.action?menuName=orgList&orgId=${item.org.id}" target="dialog">${item.org.orgName}</a> 注意:orgId是動態(tài)傳入的參數(shù),這里指該員工所在的部門編號。 2、在himenu-config.xml中配置部門樹的后面加上這么一段 <void property="filter"> <string>org.cis.filter.orgCollectionProcessor</string> </void> 注意:string標(biāo)簽內(nèi)的是寫過濾數(shù)據(jù)的類。對樹的數(shù)據(jù)進(jìn)行過濾,提供兩種接口方式對數(shù)據(jù)進(jìn)行過濾 MenuFilterProcessor 在獲取數(shù)據(jù)之前填加過濾器;MenuCollectionProcessor 在獲取數(shù)據(jù)之后再對數(shù)據(jù)做整理.具體方法查看java-doc的API。 而例子的orgCollectionProcessor類代碼: public class orgCollectionProcessor implements MenuCollectionProcessor {
public Collection getCollection(Collection coll, Map<String, String> map) { // TODO Auto-generated method stub //coll - 當(dāng)前節(jié)點(diǎn)下一級節(jié)點(diǎn)的數(shù)據(jù)集合 //map 動態(tài)的傳入數(shù)據(jù),以map的形式 //傳入一個(gè)員工的所在的部門Id,返回該員工所在的部門結(jié)構(gòu)樹 int orgId=Integer.parseInt(map.get("orgId").toString()); for (Iterator iterator = coll.iterator(); iterator.hasNext();) { Object obj = (Object) iterator.next(); if(obj instanceof HiOrg){ HiOrg hiorg = (HiOrg)obj; if(hiorg.getId()!=orgId) { iterator.remove(); coll.remove(obj); } } } return coll; } } 注:該文檔由J-Hi愛好者"無可"提供,他的QQ號為924372739,歡迎大家與他在技術(shù)上多多交流 樹形菜單能很好的呈現(xiàn)菜單項(xiàng)之前的從屬關(guān)系,結(jié)構(gòu)清晰明了。J-hi平臺提供了自定義樹形菜單的功能,通過簡單的配置即可實(shí)現(xiàn)。 本文主要介紹通過樹形菜單選擇帶回節(jié)點(diǎn)值的實(shí)現(xiàn)方法。以選擇帶回行政區(qū)劃位置為例。 數(shù)據(jù)庫表設(shè)計(jì):默認(rèn)帶回頁選擇界面:通過jhi自動生成代碼的功能,對于lookup xzqhwz的字段默認(rèn)是如上帶回頁面,顯然并不能表現(xiàn)行政區(qū)劃位置之間的主從關(guān)系。 樹形帶回頁面:而如果實(shí)現(xiàn)如下頁面的展示,將會清晰方便許多。 雙擊即可帶回節(jié)點(diǎn),也可通過配置帶回節(jié)點(diǎn)的各級父節(jié)點(diǎn)。 下面是配置的方法: 配置方法:修改xml修改C:"Program"hi-studio"eclipse"workspace"earch5"web"WEB-INF"config"himenu-config.xml 在代碼末尾: </object> </java> 之前插入:(注意修改其中參數(shù)) <void method="put"> <string>zdtree</string> <object class="org.hi.base.menu.strutsmenu.WebDynamicMenuDefine"> <void property="keymap"> <object class="java.util.HashMap"> <void method="put"> <string>id</string> <string>parentxzqhwz</string> </void> </object> </void> <void property="parent"> <string>id</string> </void> <void property="child"> <string>parentxzqhwz</string> </void> <void property="childValue"> <int>0</int> <! 新版本jhi應(yīng)為:<string>0</string> > </void> <void property="menuName"> <string>zdtree</string> </void> <void property="beanName"> <string>org.hi.zdtree.model.Xzqhwz</string> </void> <void property="submenuName"> <string>zdtree</string> </void> <void property="title"> <string>行政區(qū)劃位置</string> </void> <void property="titleField"> <string>xzqhwz</string> </void> <void property="needShow"> <boolean>true</boolean> </void> <void property="javascript"> <string> function backAgent(id,orgName){ if(opener.document.getElementById('yzjbxx.xzqhwz')!=null){ opener.document.getElementById('yzjbxx.xzqhwz').value=orgName; } <!帶回到相應(yīng)的頁面的相應(yīng)文本框。 > else{ opener.document.getElementById('xzqhwz.pxzqhwz').value=orgName; opener.document.getElementById('xzqhwz.parentxzqhwz.id').value=id; window.close(); } } </string> </void> <void property="action"> <string>{js}backAgent([#id],"'[#xzqhwz]"');</string> <!在樹型結(jié)構(gòu)上通過雙擊一個(gè)節(jié)點(diǎn),獲取帶回該節(jié)點(diǎn)的各級上節(jié)點(diǎn) <string>{js}backAgent([#id],"'[#parentxzqhwz.parentxzqhwz.parentxzqhwz.xzqhwz][#parentxzqhwz.parentxzqhwz.xzqhwz][#parentxzqhwz.xzqhwz][#xzqhwz]"');</string> > </void> </object> </void> 修改XzqhwzEdit.jsp頁面將C:"Program"hi-studio"eclipse"workspace"earch5"web"zdtree"XzqhwzEdit.jsp中 onclick="xzqhwz_lookupPOP('parentxzqhwz')" 改為: onclick="window.open('/tree.action?menuName=zdtree','部門','width=300,height=500,left=10,top=20,location=no,status=no')" 這樣,到Xzqhwz的頁面,點(diǎn)擊父節(jié)點(diǎn)的帶回按鈕即可看到效果,同樣lookup到xzqhwz字段的地方也修改Edit.jsp頁面的onclick動作就行啦。
該文檔是對J-Hi樹形的入門級介紹,J-Hi的樹功能還有:節(jié)點(diǎn)的過濾,lazy加載,一個(gè)節(jié)點(diǎn)可以多個(gè)圖標(biāo)、復(fù)選框效果,多個(gè)實(shí)體組合形成一棵樹,我們將在以后繼續(xù)講解
注:該文檔由J-Hi愛好者"馮思豪"提供,他的QQ號為382600911,歡迎大家與他在技術(shù)上多多交流
J-Hi平臺在考慮到開發(fā)時(shí)與發(fā)布后對信息、安全、效率等方面的要求不同,從而提供了設(shè)置開發(fā)模式與發(fā)布模式的開關(guān)。這個(gè)開關(guān)配置在src下的hiFrameworkConfig.properties文件中。
hi.depolyment.published=true
下面讓我們就這個(gè)開關(guān)項(xiàng)做如下分析,如果值為true,也就是發(fā)布模式,它到底會影響哪些東西:信息內(nèi)容 1)菜單中“權(quán)限”、“權(quán)限資源”將不在顯示,因?yàn)橐坏⒆龊玫捻?xiàng)目發(fā)布后,這些信息是不能讓客戶維護(hù)的。 2)菜單中“觸發(fā)器”、“消息管理”將不可見,因?yàn)橐坏┒〞r(shí)服務(wù)設(shè)定好,一般來說客戶很少會調(diào)整,即使是調(diào)整也應(yīng)該是由開發(fā)人員來調(diào)整觸發(fā)的周期與頻率。對于消息管理也是一樣。 3) 整個(gè)“國際化”菜單項(xiàng)全部不顯示,這其中包括“多語言參數(shù)”、“語言編碼”、“時(shí)區(qū)”,原因這些內(nèi)部均應(yīng)該在開發(fā)過程中將信息內(nèi)容一并編輯完成。比如有一個(gè)語言編碼就要有一套多語言參數(shù)與之對應(yīng),因些一旦系統(tǒng)上線,所有國際化部分的維護(hù)功能也應(yīng)該同時(shí)完成。 4)“應(yīng)用配置”列表中,“刪除”圖標(biāo)將不再顯示,因?yàn)槿绻到y(tǒng)上線,系統(tǒng)中的一些基礎(chǔ)配置項(xiàng)是不能刪除,而只能更改的 對于這個(gè)功能的控制,是在main.jsp中,加入一個(gè)變量,代碼如下 <%// 是否已發(fā)布的開關(guān),其目的是如果為true則關(guān)閉那些對終端用戶不可見的功能按鈕 %>
建議大家以后在自己采用J-Hi開發(fā)的系統(tǒng)中也可以采用該方式來控制頁面,這樣就可以做到即不影響開發(fā),而在項(xiàng)目提交給用戶時(shí)同樣保證某些只在開發(fā)時(shí)才能用到的按鈕或功能,只要改變一個(gè)開關(guān)就可以控制。 <ws:set name="published" value="@org.hi.framework.HiConfigHolder@getPublished()" /> 安全 如果采用了發(fā)布模式后,頁面提交的URL將會被加密,而開發(fā)模式URL則是以明文顯示,開關(guān)則試前后URL的效果如下: http://localhost:8080/hiUserEdit.action?hiUser.id=1
由此可以看出URL問號后的參數(shù)部分全部通過了加密處理,這樣使您做出的系統(tǒng)更安全,通過使別人URL分析不出你要獲取的信息參與也推導(dǎo)不出系統(tǒng)的結(jié)構(gòu)http://localhost:8080/hiUserEdit.action?cf4a9619dd97fc2689fb63048237404f 效率 1)如果是發(fā)布模式,DWZ版的所有js文件將采用壓縮的文件,而非一個(gè)一個(gè)的離散文件,這樣系統(tǒng)的傳輸?shù)膬?nèi)容會更少,具體的方式參見styles.jsp文件 2)如果是發(fā)布模式,系統(tǒng)在啟動時(shí)一次性加載枚舉實(shí)體、枚舉值、多語言參數(shù)、應(yīng)用配置這些常量性的信息進(jìn)入緩存,在取這些信息時(shí)系統(tǒng)會自動從緩沖中取而并非每都要查詢數(shù)據(jù)庫。舉例來說,性別是一個(gè)下拉的枚舉,如果是發(fā)布模式只直接從緩沖區(qū)中取數(shù)據(jù),而如果是開發(fā)模式它就會去數(shù)據(jù)庫中取數(shù)據(jù),如果是一個(gè)人員列表,那么有幾個(gè)要顯示枚舉的地方就要去數(shù)據(jù)庫取幾次。因此開發(fā)模式的運(yùn)行效率要遠(yuǎn)遠(yuǎn)低于發(fā)布模式,但開發(fā)模式更有實(shí)效性,只要數(shù)據(jù)有任何變化都可以實(shí)體的反應(yīng)出來,即使是在同一個(gè)事務(wù)中,而發(fā)布模式只能在一個(gè)事務(wù)完成之后再能做數(shù)據(jù)同步處理(即內(nèi)存與數(shù)據(jù)庫之間的數(shù)據(jù)同步) |