ExtJS4+Servlet/Struts2+JSON+accordion佈局動態Ext.tree.Panel菜單


       先貼個圖給大家,實現的是一個Accordion佈局的動態菜單,俗稱手拉琴佈局,切入正題:
       首先構造出一個窗口(Ext.window.Window),佈局選擇Accordion,代碼:
var win = Ext.create("Ext.window.Window", {
				title : "Accordion佈局動態菜單",
				width : 300,
				height : 500,
				iconCls : "icon-accordion",
				autoScroll : false,
				layout : 'accordion', //設置佈局
				layoutConfig : {
					animate : true //動態切換樹空間
				}
			});
			win.show();


       然後向後臺發送AJAX請求,獲取窗口的面板列表:
ajax({
				url : "/Accordion/accordion",//獲取面板的地址
				params : {
					action : "list"
				},
				callback : addTree
			});


       這裏對Ext.Ajax.request方法做了一個簡易的封裝:
var ajax = function(config) { //封裝、簡化AJAX
			Ext.Ajax.request({
				url : config.url, //請求地址
				params : config.params, //請求參數
				method : 'post', //方法
				callback : function(options, success, response) {
					config.callback(Ext.JSON.decode(response.responseText));
					//調用回調函數
				}
			});
			return false;
		};


       在SERVLET代碼裏面,準備樹面板的數據,在doPost方法中根據action判斷是獲取面板列表還是樹節點,然後將數據發送到頁面,renderText方法不是很關鍵,大家可以去下載源碼看看,這裏就不寫出來:
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		String action = request.getParameter("action");
		initHeader(response);
		if(action.equals("list")){//獲取屬面板列表
			renderText(this.getTreePanelList(), response);
		}else if(action.equals("node")){
			renderText(this.getTreeNodeList(request.getParameter("id")), response);
		}
	}
       這裏獲取的樹面板列表,調用方法:
	public String getTreePanelList(){
		JSONArray array = new JSONArray();
		for (int i = 0; i < 5; i++) { //生成5個屬面板
			JSONObject json = new JSONObject();
			json.element("id", i+1);
			json.element("iconCls", "icon-panel");
			json.element("title", "Accordion菜單"+(i+1));
			array.add(json);
		}
		return array.toString();
	}
 通過Google Chrome的開發工具來查看獲取的樹面板列表數據:

 在獲取屬面板列表成功之後,執行addTree回調函數,根據獲取的數據生成樹面板(Ext.tree.Panel)樹面板添加進窗口中,在生成樹面板之前得先給樹面板的樹註冊一個數據源以及爲數據源指定數據模型,數據模型的作用主要是可以將自己想要的業務數據即和樹展示無關的數據傳遞到頁面,方便使用:
function addTree(data){
				for ( var i = 0; i < data.length; i++) {
					win.add(Ext.create("Ext.tree.Panel", {
						title : data[i].title,
						iconCls : data[i].iconCls,
						autoScroll : true,
						rootVisible : false,
						viewConfig : {
							loadingText : "正在加載..."
						},
						store : createStore(data[i].id)
					}));
					win.doLayout();	
				}
			}
			var model = Ext.define("TreeModel", { //定義樹節點數據模型
				extend : "Ext.data.Model",
				fields : [ {name : "id",type : "string"},
				           {name : "text",type : "string"}, 
				           {name : "iconCls",type : "string"}, 
				           {name : "leaf",type : "boolean"} 
				         ]
			});
		   var createStore  =  function(id){ //創建樹面板數據源
			   var me = this;
			   return Ext.create("Ext.data.TreeStore",{
				   defaultRootId : id, //默認的根節點id
				   model : model,
				   proxy : {
					   type : "ajax", //獲取方式
					   url : "/Accordion/accordion?action=node" //獲取樹節點的地址
				   },
				   clearOnLoad : true,
				   nodeParam : "id"//設置傳遞給後臺的參數名,值是樹節點的id屬性
			   });
		   };
最後就是實現如果生成樹節點的的數據:
	public String getTreeNodeList(String id){ //獲取樹節點的數據
		JSONArray array = new JSONArray();
		for (int j = 0; j < 5; j++) {
			JSONObject json = new JSONObject();
			json.element("id", id + "-" +(j+1));
			json.element("text", "樹節點-"+ id + "-" +(j+1));
			if((j+1) % 2 == 0 && id.length() <= 3){ //判斷順序爲偶數的節點,及層數不超過三層的節點可以加載子節點
				json.element("leaf", false); //通過leaf屬性來控制樹節點是否是葉子節點(沒有子節點的節點),能否加載數據
			}else{
				json.element("leaf", true);
			}
			array.add(json);
		}
		return array.toString();
	}
      然而通過這些代碼實現後會發現一個屬面板展示上的BUG,樹面板裏面的樹空間的寬度不正確:
      這是一個Ext4的BUG,不過不要緊,BUG總是可以會修復的,將addTree的代碼改造一下,給樹面板註冊一個afterLayout的監聽器,實例當中的代碼是改造後的,只是跟大家說明下這段代碼的用途:
function addTree(data){
				for ( var i = 0; i < data.length; i++) {
					win.add(Ext.create("Ext.tree.Panel", {
						title : data[i].title,
						iconCls : data[i].iconCls,
						autoScroll : true,
						rootVisible : false,
						viewConfig : {
							loadingText : "正在加載..."
						},
						store : createStore(data[i].id),
						listeners : {
							afterlayout : function(){
								if(this.getView().el){
									var el = this.getView().el;
									var table = el.down("table.x-grid-table");
									if(table){
										table.setWidth(el.getWidth());
									}
								}
							}
						}
					}));
					win.doLayout();
					
				}
			}
   
 最後一個話題,在STRUTS中如何實現,很簡單:也是準備數據,然後將數據發送到頁面就可以!
 這樣,一個Accordion佈局整合SERVLET/STRUTS2+JSON+動態Ext.tree.Panel菜單就OK了!
 下面是展示兩張將這個模塊應用到系統中的效果:




Ext還能做什麼?只有想不到的,沒有做不到了,進入http://blog.csdn.net/leecho571/article/details/8207102感受Ext帶來的新的體驗

實例下載:http://download.csdn.net/detail/leecho571/3901796,
大家可以去看我的另外一篇文章,裏面有更深入的關於Ext.tree.Panel和Ext.tab.Panel的使用

看文章評論一下是美德,你的評論是我最大的動力!!



     
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章