這幾天做動態菜單用到了這個外掛程式,目前用的很廣泛的一個開源架構,最新發行的QUI架構就是用這個外掛程式開發的菜單部分,因此還是很值得深入研究和學習,通過使用感覺功能很豐富,好多函數不用自己開發和編寫,官網上有很詳盡的API可以參考,用著算順手但學習使用的過程中也遇到了一些困難,聽過反覆測試和查資料都理解了,但也在思考一個問題,怎麼樣才能使得最快的時間從接觸一個新東西到靈活掌握的程度?
這個不僅僅是一個樹形結構的菜單,每個節點左邊可以有一個複選框,看了看也挺簡單的,只需要在setting裡面配置一個checked屬性即可。
目前經驗覺得這個用在組織圖、分類、尤其是許可權,如果用這個外掛程式完成會很完美和自己的商務邏輯相結合。
原理是很容易理解就不過多說它的原理了,大致同ajax非同步請求原理相同,看一遍介紹你也就明白了,這個架構全部是非同步請求資料,提高了使用者體驗度。
在學這個過程中,本人有如下幾點浪費了點時間拿出來和大家分享一下,以便大家下次項目中使用更容易上手。
待用資料與動態資料
這個架構支援XM、json等多種資料格式,建議大家使用json格式資料覺得效果好一些、載入的時候快一些,關於資料格式可以參考官網給的一些資料,官網上面給的都是一些假資料,如果動態產生菜單淡然需要從資料庫裡面查詢出來,然後轉換成json字串了,需要自己解析json字串。
在之前做項目中還真沒有自己好好研究一下解析字串,現在用到了只能現學現弄這樣減慢了開發效率,這應該屬於開發基礎。
我自己試著寫幾種方法解析、試著引用網上的方法、幾種迭代都不能產生正確的字串,最後一種還是解析出來了,從資料庫查詢出來的是list列表,然後把他解析成了一個json串,所有資料都顯示在頂層菜單,檢查json串和給的例子是一樣的但是還是出不來摺疊效果。
原來並不是解析json串不對,而是它列印到介面上是一級一級列印,並不是一下全部查出來都列印出去,這樣當然就在一個層級上了,這也是所說的靜態載入全部節點,很讓人噁心的json串,強烈建議大家數量掌握幾種解析json、array等以及相互轉換的方法,這些是很基本的能力,平時會經常用的。
isParent節點
我們一看都知道這個節點表示是不是父節點,它有什麼含義呢,在使用中我發isParent為true時,表示的是該節點左邊接受單機事件,也就是會有一個展開符號,每次點擊會觸發一次非同步提交資料,請求子節點資料載入到頁面上。正常情況下如果你不點擊父節點所有子節點是不載入到頁面的。
後台產生樹json串代碼
treeList=resourceService.list(childMap); JSONArray jsonArray=new JSONArray(); for(Organization organization:treeList) { JSONObject jsonObject=new JSONObject(); jsonObject.put("id",organization.getId()); jsonObject.put("pid",organization.getPid()); jsonObject.put("name",organization.getName()); //判斷所選擇節點是否是父節點,如果是設定isParent屬性為true,不是設定為false Map subchildMap=new LinkedHashMap(); subchildMap.put("sqlid","SubChildLst"); subchildMap.put("id",organization.getId()); List<Organization> subtreeList=new ArrayList<Organization>(); subtreeList=resourceService.list(subchildMap); if(subtreeList.size() > 0 ) { jsonObject.put("isParent","true"); }else { jsonObject.put("isParent","false");} boolean isChecked=resourceService.IsChecked(contactid,organization.getId()); if (null==contactid || "".equals(contactid) || "null".equals(contactid)) { jsonObject.put("checked","false");}else {if (isChecked) {jsonObject.put("checked","true");}else {jsonObject.put("checked","false");}} jsonObject.put("open","false"); jsonArray.put(jsonObject); }String json=JsonUtil.toJson(jsonArray);
checked節點
該樹形是選中的節點,這個節點也很有用,比如載入一個商品它是屬於哪些分類的,在載入樹的過程中,要把預設選中的項目載入上來,這個你想怎麼實現呢。
動態載入預設選中的節點,用了半天的時間才想出怎麼弄,有時候並不是我們不會寫代碼而是沒有思路,有時有思路但是行不通這時就需要我們轉換思考角度,在編程中也要注意從多角度思考,不要鑽到一個點上去。
解決動態載入預設選中項我用的是傳遞參數,在一般的頁面上面傳遞參數覺得很容易,我要用的這個頁面是一個彈出頁面,使用的是window.open屬性,在彈出框上動態載入菜單並把選中的選中,ztree從官網上看API說是不能夠傳遞參數,有一個otherparm屬性可說是只接受靜態參數,是一個一個的鍵值對,我在value處又加了一個js函數,通過這個函數調用父表單上的一個變數的值,代碼如下;
<SCRIPT type="text/javascript">var setting = {check: {enable: true,chkStyle: "checkbox",chkboxType : { "Y" : "", "N" : "" }},//擷取json資料 async : { enable : true, url : "http://127.0.0.1:8080/contact/resource.do?method=getzTreeNodes", // Ajax 擷取資料的 URL 地址 autoParam : [ "id", "name" ], //ajax提交的時候,傳的是id值 otherParam: ["contactid",function(){ return window.opener.document.getElementById("contactid").value; }] }, data:{ // 必須使用data simpleData : { enable : true, idKey : "id", // id編號命名 pIdKey : "pId", // 父id編號命名 rootId : 0 } }, // 回呼函數 callback : { onClick : function(event, treeId, treeNode, clickFlag) { if(true) { alert(" 節點id是:" + treeNode.id + ", 節點文本是:" + treeNode.name); } }, //捕獲非同步載入出現異常錯誤的事件回呼函數 和 成功的回呼函數 onAsyncSuccess : function(event, treeId, treeNode, msg){ //alert("調用成功!"); //var nodes=getCheckedNodes(true)); //alert(nodes); }, beforeClick: beforeClick,onCheck: onCheck } }; function beforeClick(treeId, treeNode) {var zTree = $.fn.zTree.getZTreeObj("treeDemo");zTree.checkNode(treeNode, !treeNode.checked, null, true);return false;}var code;function showCode(str) {if (!code) code = $("#code");code.empty();code.append("<li>"+str+"</li>");}$(document).ready(function(){$.fn.zTree.init($("#treeDemo"), setting);//setCheck();}); function onCheck(e,treeId,treeNode) {var zTree = $.fn.zTree.getZTreeObj("treeDemo"),nodes = zTree.getCheckedNodes(true),v = "";var ids="";for (var i=0, l=nodes.length; i<l; i++) {v += nodes[i].name + ",";ids+=nodes[i].id+",";}if (ids.length > 0 ) ids = ids.substring(0, ids.length-1);alert(ids);if (v.length > 0 ) v = v.substring(0, v.length-1); cityObjIds=window.opener.document.getElementById("cateSelIds").value=ids; cityObjName=window.opener.document.getElementById("cateSelName").value=v; } function getSelectedNodes() {var zTree = $.fn.zTree.getZTreeObj("treeDemo"),nodes = zTree.getCheckedNodes(true),v = "";var ids="";for (var i=0, l=nodes.length; i<l; i++) {v += nodes[i].name + ",";ids+=nodes[i].id+",";}if (ids.length > 0 ) ids = ids.substring(0, ids.length-1);alert(ids);if (v.length > 0 ) v = v.substring(0, v.length-1);//var cityObj = $("#citySel");//var cityObjIds = $("#citySelIds");//給父表單updateContact.jsp中所屬分類賦值 window.opener.document.getElementById("cateSelIds").value=ids; window.opener.document.getElementById("cateSelName").value=v; }function winClose(){window.close();}</SCRIPT> 運行效果,動態下拉式清單樹
在工作中別人給你講解代碼或者一點點詳細的講解幾乎是沒有的,我們那個經理只說你用那個ztree做一下那個動態菜單。
作為一個程式員要能讀懂別人代碼
讓我看別人的代碼,我說看著看著就不想看了,還不如我自己動手寫呢,其實,看別人代碼一直覺得挺沒意思的,現在想法改變了些,別人寫的代碼不管是好是壞,我們都值得看一看借鑒借鑒,一直在提高班學習沒有怎麼看別人寫的代碼到底是怎麼樣的,覺得提高班人寫代碼無論品質如何,風格都是一樣的
注釋多、空行多、格式規範,易讀性很強,這就和學英語一樣,只聽標準音是不行的,需要挺標準音的同時也要聽聽方言,這樣才能讓我們的閱讀代碼的能力真正的提高。
作為一個程式員或者開發人員有不合適的地方要主動解決,並去最佳化。
前幾天遇到了一個問題,需要通過一個父節點ID,拿到他下面的所有子節點列表或ID,在給My Code中用預存程序實現的但用起來運行效率較慢,專案經理讓我最佳化最佳化預存程序可以看懂但不知道該最佳化哪裡,從網上找了找找到一個演算法替換後果然查詢變快了。
說一下學習一個新東西的過程
有時讓你做一個東西往往會用到新東西,一個你沒有接觸過的東西,在這個時候我們怎麼樣才能最快的學會了並且把任務做出來。
覺得在項目中該多思考、有時甚至可以不動手但是一定要多去思考,而不是別人告訴你怎麼做怎麼做,舉一個最簡單的例子post提交和get提交有什麼區別?一個不起眼的問題如果你沒有認真思考過,有時在某個時刻你會因此遇到一個小障礙,覺得這個跟解一道數學題一樣,只有把每個知識點理解了、相互之間能聯想到一起,達到各種知識綜合靈活運用,做項目的過程中才誰能得心應手,也容易達到米老師所講的最高境界。