日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

ExtJS专题-TreePanel(1)

發布時間:2023/11/30 javascript 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ExtJS专题-TreePanel(1) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

這次我們來學習下ExtJS中的樹面板(TreePanel),很多人都說,只是為了樹,都要好好學習ExtJS!可見大家對Tree的一往情深。從另一方面來說,Tree這種結構在實際項目中也的確用得相當廣泛,所以我們很有必要研究一下它。這次我們完成的樹大致上有這樣的功能:它的節點是動態異步從后臺(存儲在數據庫中一張電子產品分類表)加載的,節點之間可以拖曳,節點可以編輯,同時還支持右鍵菜單,而且,它能夠和TabPanel結合構成經典的布局方式。呵呵,是不是很強大?!大家已經看到,我們組件的講解是逐步遞推的,所以我們這里也會用到剛學過的GridPanelTabPanel這些實用的面板。我們看效果先:

?

?

?

好啦,洪哥,我們動手吧!

?

1.????? 首先還是主要的顯示頁面tree.html,這里有兩個地方要注意一下,一個是我們引用的JS如果采用GBK的默認編碼,瀏覽器會顯示未結束的字符串常量的錯誤,所以我們一般會修改JS文件的編碼方式為UTF-8,或者在導入JS時加上編碼字符集。第二個是我們要定義一個顯示TreePanelDIV

?

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>Insert title here</title>

<link rel="stylesheet" type="text/css" href="resources/css/ext-all.css" />

<script type="text/javascript" src="resources/js/ext-base.js"></script>

<script type="text/javascript" src="resources/js/ext-all.js"></script>

<script type="text/javascript" src="resources/js/tree.js" charset="gbk"></script>

</head>

<body>

<div id="tree-panel" style="overflow:auto; height:300px;width:200px;border:2px solid #c3daf9;"></div>

</body>

</html>

?

2.????? 然后是我們的主體JS文件,tree.js,為了凸顯主題,這個我已經做了必要的簡化,還做了詳細的注釋,大家好好看一下。

?

Ext.onReady(function() {

??? Ext.QuickTips.init();// 浮動信息提示

??? Ext.BLANK_IMAGE_URL = 'resources/images/default/s.gif';// 替換圖片文件地址為本地

?

??? // 創建一個簡寫

??? var Tree = Ext.tree;

??? // 定義根節點的Loader

??? var treeloader = new Tree.TreeLoader({

??????????? // dataUrl : 'tree.jsp'//這里可以不需要指定URL,在加載前事件響應里面設置

??????????? });

?

??? // 添加一個樹形面板

??? var treepanel = new Tree.TreePanel({

??????? // renderTo:"tree_div",//如果使用renderTo,則不能使用setRootNode()方法,需要在TreePanel中設置root屬性。

??????? el : 'tree-panel',// 將樹形添加到一個指定的div,非常重要!

??????? region : 'west',

??????? title : '功能菜單',

??????? width : 200,

??????? minSize : 180,

??????? maxSize : 250,

??????? split : true,

??????? autoHeight : false,

??????? frame : true,// 美化界面

??????? // width : 200,//面板寬度

??????? // title : '可編輯和拖動的異步樹',//標題

??????? // autoScroll : true, // 自動滾動

??????? enableDD : true,// 是否支持拖拽效果

??????? containerScroll : true,// 是否支持滾動條

??????? rootVisible : true, // 是否隱藏根節點,很多情況下,我們選擇隱藏根節點增加美觀性

??????? border : true, // 邊框

??????? animate : true, // 動畫效果

??????? loader : treeloader

??????????? // 樹加載

??????? });

??? // 異步加載根節點

??? var rootnode = new Tree.AsyncTreeNode({

??????????????? id : '0',

??????????????? text : '家電品牌總類',

??????????????? draggable : false,// 根節點不容許拖動

??????????????? expanded : true

??????????? });

?

??? // tree設置根節點

??? treepanel.setRootNode(rootnode);

?

??? // 響應加載前事件,傳遞node參數

??? treepanel.on('beforeload', function(node) {

??????????????? treepanel.loader.dataUrl = 'tree.jsp?parentId=' + node.id; // 定義子節點的Loader

??????????? });

??? // 渲染樹形

??? treepanel.render();

??? // 展開節點,第一個參數表示是否級聯展開子節點

??? rootnode.expand(true);

?

??? // 設置樹的點擊事件

??? function treeClick(node, e) {

??????? if (node.isLeaf()) {

??????????? e.stopEvent();

??????????? var n = contentPanel.getComponent(node.id);

??????????? if (!n) {

??????????????? var n = contentPanel.add({

??????????????????????????? 'id' : node.id,

??????????????????????????? 'title' : node.text,

??????????????????????????? closable : true,

??????????????????????????? autoLoad : {

??????????????????????????????? url : 'tabFrame.jsp?url=grid.html',

??????????????????????????????? scripts : true

??????????????????????????? } // 通過autoLoad屬性載入目標頁,如果要用到腳本,必須加上scripts屬性

??????????????????????? });

??????????? }

??????????? contentPanel.setActiveTab(n);

??????? }

??? }

??? // 增加鼠標單擊事件

??? treepanel.on('click', treeClick);

?

??? // 定義右鍵菜單

??? var rightClick = new Ext.menu.Menu({

??????????????? id : 'rightClickCont',

??????????????? items : [{

??????????????????????????? id : 'rMenu1',

??????????????????????????? text : '添加節點',

??????????????????????????? // 增加菜單點擊事件

??????????????????????????? handler : function() {

??????????????????????????????? alert('添加節點的實現!');

??????????????????????????? }

??????????????????????? }, {

??????????????????????????? id : 'rMenu2',

??????????????????????????? text : '編輯節點'

??????????????????????? }, {

??????????????????????????? id : 'rMenu3',

??????????????????????????? text : '刪除節點'

??????????????????????? }]

??????????? });

??? // 增加右鍵點擊事件

??? treepanel.on('contextmenu', function(node, event) {// 聲明菜單類型

??????????????? event.preventDefault();// 阻止瀏覽器默認右鍵菜單顯示

??????????????? rightClick.showAt(event.getXY());// 取得鼠標點擊坐標,展示菜單

??????????? });

?

??? /*

??? ?* 設置tree的節點放置函數此函數有一個很重要的參數對象e e對象有三個重要的屬性,分別為dropNode,target,point

??? ?* 1.dropNode為在拖動時鼠標抓住的節點 2.target為將要放置在某處的節點

??? ?* 3.point為被放置的狀態,分別有append表示添加,above節點的上方,below節點的下方。

??? ?*

??? ?*/

??? treepanel.on('nodedrop', function(e) {

?

??????????????? if (e.point == 'append') {

??????????????????? alert('當前"' + e.dropNode.text + '"劃到"' + e.target.text

??????????????????????????? + '"里面!');

??????????????? } else if (e.point == 'above') {

??????????????????? alert('當前"' + e.dropNode.text + '"放在了"' + e.target.text

??????????????????????????? + '"上面!');

??????????????? } else if (e.point == 'below') {

??????????????????? alert('當前"' + e.dropNode.text + '"放在了"' + e.target.text

??????????????????????????? + '"下面!');

??????????????? }

??????????? });

?

??? // 在原有的樹形添加一個TreeEditor

??? var treeEditer = new Tree.TreeEditor(treepanel, {

??????????????? allowBlank : false

??????????? });

??? /*

??? ?* 為創建的treeEditer添加事件 有兩個事件最為常用,一個為beforestartedit另一個為complete

??? ?* 從名字就可以看出,beforestartedit事件是在編輯前的事件,因此可以通過它來判斷那些節點可以編輯那些不可以。

??? ?* complete為編輯之后的事件,在這里面可以添加很多事件,比如添加一個Ext.Ajax向后臺傳送修改的值等等。

??? ?*/

??? treeEditer.on("beforestartedit", function(treeEditer) {

??????????????? var tempNode = treeEditer.editNode;// 將要編輯的節點

??????????????? if (tempNode.isLeaf()) {// 這里設定葉子節點才容許編輯

??????????????????? return true;

??????????????? } else {

??????????????????? return false;

??????????????? }

??????????? });

?

??? treeEditer.on("complete", function(treeEditer) {

??????????????? alert("被修改為" + treeEditer.editNode.text);

??????????? });

?

??? // 1)通過TabPanel控件的html屬性配合<iframe>實現。該方法是利用

??? // html屬性中包含<iframe>的語法來調用另一個頁面,具體見代碼。

??? // 2)通過TabPanel控件的autoLoad屬性實現。該方法是利用autoLoad屬性,它有很多參數,

??? // 其中有兩個比較重要,url表示要載入的文件,scripts表示載入的文件是否含有腳本,該屬性相當重要,

??? // 如果在新的頁面中要創建Ext控件,必須指定該參數。該方法實現較前一個復雜,因為引入的文件不是一個完整的html文件,

??? // 有可能只是內容的一部分,但是資源占用較少,而且載入速度較快(它有一個載入指示)

?

??? // 添加第一個節點(html)

??? treepanel.root.appendChild(new Ext.tree.TreeNode({

??????? id : 'htmlPanel',

??????? text : '通過html打開',

??????? listeners : {

??????????? 'click' : function(node, event) {

??????????????? event.stopEvent();

??????????????? var n = contentPanel.getComponent(node.id);

??????????????? if (!n) { // 判斷是否已經打開該面板

??????????????????? n = contentPanel.add({

??????????????????????? 'id' : node.id,

??????????????????????? 'title' : node.text,

??????????????????????? closable : true, // 通過html載入目標頁

??????????????????????? html : '<iframe scrolling="auto" frameborder="0" width="100%" height="100%" src="grid.html"></iframe>'

??????????????????? });

??????????????? }

??????????????? contentPanel.setActiveTab(n);

??????????? }

??????? }

??? }));

?

??? // 添加第二個節點(autoLoad)

??? treepanel.root.appendChild(new Ext.tree.TreeNode({

??????????????? id : 'autoLoadPanel',

??????????????? text : '通過autoLoad打開',

??????????????? listeners : {

??????????????????? 'click' : function(node, event) {

??????????????????????? event.stopEvent();

??????????????????????? var n = contentPanel.getComponent(node.id);

??????????????????????? if (!n) { // //判斷是否已經打開該面板

??????????????????????????? n = contentPanel.add({

??????????????????????????????????????? 'id' : node.id,

??????????????????????????????????????? 'title' : node.text,

??????????????????????????????????????? closable : true,

??????????????????????????????????????? autoLoad : {

??????????????????????????????????????????? url : 'tabFrame.jsp?url=grid.html',

??????????????????????????????????????????? scripts : true

??????????????????????????????????????? } // 通過autoLoad屬性載入目標頁,如果要用到腳本,必須加上scripts屬性

??????????????????????????????????? });

??????????????????????? }

??????????????????????? contentPanel.setActiveTab(n);

??????????????????? }

??????????????? }

??????????? }));

?

??? // 右邊具體功能面板區

??? var contentPanel = new Ext.TabPanel({

??????? region : 'center',

??????? enableTabScroll : true,

??????? activeTab : 0,

??????? items : [{

??????????? id : 'homePage',

??????????? title : '首頁',

??????????? autoScroll : true,

??????????? html : '<div style="position:absolute;color:#ff0000;top:40%;left:40%;">Tree控件和TabPanel控件結合功能演示</div>'

??????? }]

??? });

?

??? new Ext.Viewport({

??????????????? layout : 'border', // 使用border布局

??????????????? defaults : {

??????????????????? activeItem : 0

??????????????? },

??????????????? items : [treepanel, contentPanel]

??????????? });

?

});

?

3.?? 再接著是tree.jsExtJSTreeLoader調用的tree.jsp,在目錄樹上點擊TreeNode后會加載下一級節點。tree.jsp負責TreeNode點擊后,傳回由下一級節點構造的JSON數據,也就是前臺樹異步請求訪問的后臺WEB組件。它會調用JAVABEAN操作數據庫,得到每個節點的子節點數據。這里由于我們后臺需要返回給客戶端JSON格式的數據,也就是需要操作JSON數據格式。所以我們首先要下載JSON-lib,地址:http://json-lib.sourceforge.net/打開網址后,首頁上有一段話:
?Json-lib requires (at least) the following dependencies in your classpath:
????? jakarta commons-lang 2.3
????? jakarta commons-beanutils 1.7.0
????? jakarta commons-collections 3.2
????? jakarta commons-logging 1.1.1
????? ezmorph 1.0.4
??
需要下載上述jar文件,配合JSON-lib 一起使用。

?? commons
下載地址:http://commons.apache.org/
?? ezmorph
下載地址:
http://ezmorph.sourceforge.net
??
或者,到 http://www.docjar.com 搜索下載。

?? JSON
的用法,我們已經提過多次,大家可參考相關文檔??纯?/span>tree.jsp的代碼:

?

<%@ page language="java" pageEncoding="utf-8"%>

<jsp:useBean class="org.leno.javabean.JSONTree" id="JSONTree"></jsp:useBean>

<%

??? String parentId = "";

??? if (request.getParameter("parentId") != null) {

??????? parentId = request.getParameter("parentId").toString();

??? }

??? JSONTree.setparentId(parentId);

%>

<%=JSONTree.getJSONString()%>

?

4.????? ?后臺用到的JAVA,這里包括訪問數據庫的數據源工廠類DataSourceFactory(這里用到了DBCP連接池,大家要記得導入連接sqlserver 2000數據庫和dbcp連接池的相關JAR包!),定義樹節點的屬性,包括節點ID、Text、圖標、是否為葉子節點、是否展開等的類JSONTreeNode,還有類似DAO能夠封裝數據訪問和格式轉換細節的JSONTree。

?

package org.leno.javabean;

?

import java.sql.SQLException;

import org.apache.commons.dbcp.BasicDataSource;

?

public class DataSourceFactory {

?

??? /**

??? ?* @param args

??? ?*/

??? private static BasicDataSource ds;

?

??? public static BasicDataSource getDataSource() {

??????? if (ds == null) {

??????????? ds = new BasicDataSource();

??????????? ds.setDriverClassName("com.microsoft.jdbc.sqlserver.SQLServerDriver");

??????????? ds.setUrl("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=java28");

??????????? ds.setUsername("sa");

??????????? ds.setPassword("123");

??????????? ds.setMaxActive(5);

??????? }

??????? return ds;

?

??? }

?

??? public static void main(String[] args) {

??????? // TODO Auto-generated method stub

??????? try {

??????????? System.out.println(DataSourceFactory.getDataSource()

??????????????????? .getConnection());

??????? } catch (SQLException e) {

??????????? // TODO Auto-generated catch block

??????????? e.printStackTrace();

??????? }

?

??? }

?

}

package org.leno.javabean;

?

/**

?* @author leno

?*定義樹節點的屬性,包括節點ID、Text、圖標、是否為葉子節點、是否展開等。

?*/

public class JSONTreeNode {

?

??? ? ? private String id;??????????? //ID

??? ???? private String text;????????? //節點顯示

??? ???? private String cls;?????????? //圖標

??? ???? private boolean leaf;???????? //是否葉子

??? ???? private String href;????????? //鏈接

??? ???? private String hrefTarget;??? //鏈接指向

??? ???? private boolean expandable;?? //是否展開

??? ???? private String description;?? //描述信息

??? ????

??????? get/set……

}

package org.leno.javabean;

?

import java.sql.*;

import java.util.*;

import net.sf.json.JSONArray;

?

public class JSONTree {

private String parentId;

???

??? public String getJSONString(){?????

??????? Connection con =null;

??????? Statement st = null;

??????? ResultSet rs = null;

??????? List<JSONTreeNode> treeNodeArray = null;

???????

??????? String SQLString = "SELECT * FROM Categories WHERE parentId="+this.parentId+" ORDER BY categoryId";???

???????????

??????? try

??????? {

??????????? con = DataSourceFactory.getDataSource().getConnection();

??????????? st = con.createStatement();

??????????? //查找所有擁有下級類別的類別ID

??????????? rs = st.executeQuery("SELECT parentId FROM Categories WHERE parentId>0 Group By parentId Order By parentId");???????????

???????????

??????????? StringBuffer parentIDBuffer =new StringBuffer();

??????????? parentIDBuffer.append("|");????????

??????????? while(rs.next())

??????????? {

??????????????? parentIDBuffer.append(rs.getString("parentId"));

??????????????? parentIDBuffer.append("|");

??????????? }

??????????? //得到所有的parentcategoryId列表

??????????? String parentIDString = parentIDBuffer.toString();????????

???????????

??????????? rs = st.executeQuery(SQLString);???

??????????? treeNodeArray = new ArrayList<JSONTreeNode>();

??????????? while(rs.next())

??????????? {

??????????????? JSONTreeNode treeNode = new JSONTreeNode();

??????????????? String categoryId = rs.getString("categoryId");

??????????????? treeNode.setId(categoryId);

??????????????? treeNode.setText(rs.getString("categoryName"));

??????????????? treeNode.setDescription(rs.getString("description"));?????????

//??????????????????? treeNode.setHref("rightframe.jsp?categoryId="

//????????????????????? + rs.getString("categoryId").toString());

//??????????????????? treeNode.setHrefTarget("rightFrame");??????????????

???????????????

??????????????? if (parentIDString.indexOf("|"+categoryId+"|")>=0) //父節點

??????????????????? {

??????????????????????? treeNode.setCls("folder");

??????????????????????? treeNode.setLeaf(false);

??????????????????????? treeNode.setExpandable(false);

??????????????????? }

??????????????????? else //子節點

?????????????????? {

??????????????????????? treeNode.setCls("file");

??????????????????????? treeNode.setLeaf(true);

?????????????????? ?????treeNode.setExpandable(false);

??????????????????? }

??????????????????? treeNodeArray.add(treeNode);

??????????? }

???????????

??????????? JSONArray JsonArray = JSONArray.fromObject(treeNodeArray); //得到JSON數組????

?

??????????? return JsonArray.toString();//返回JSON數據

??????? }

??????? catch(Exception e)

??????? {

??????????? System.out.println("getJSONString() of JSONTree.java throws : "+e.toString());

??????????? return "";

??????? }

??????? finally

??????? {

?????????? try {

??????? ???if(con!=null&&!con.isClosed()){

??????? ???? ???con.close();

??????? ???}

??????? } catch (SQLException e) {

??????????? // TODO Auto-generated catch block

??????????? e.printStackTrace();

??????? }

??????? }

??? }??

?

?

??? public String getparentId() {

??????? return parentId;

??? }

?

??? public void setparentId(String parentId) {

??????? this.parentId = parentId;

??? }

?

}

?

5.????? 最后是我們的數據庫腳本script.sql,大家用SQLServer 2000數據庫創建一個java28database,然后執行下列腳本即可。

?

create table Categories

(

??? categoryId int identity(1,1) primary key,

??? categoryName varchar(30),

??? description varchar(100),

??? parentId int

)

insert into Categories values('電腦','關于電腦',0);

insert into Categories values('電視機','關于電視機',0);

insert into Categories values('數碼相機','關于數碼相機',0);

insert into Categories values('冰箱','關于冰箱',0);

insert into Categories values('聯想電腦','關于聯想電腦',1);

insert into Categories values('創維電視機','關于創維電視機',2);

insert into Categories values('索尼相機','關于索尼相機',3);

insert into Categories values('海爾冰箱','關于海爾冰箱',4);

?

insert into Categories values('旭日電腦','關于旭日電腦',5);

insert into Categories values('天逸電腦','關于天逸電腦',5);

insert into Categories values('創維液晶電視','關于創維液晶電視機',6);

insert into Categories values('索尼M23相機','關于索尼M23相機',7);

insert into Categories values('海爾G1冰箱','關于海爾G1冰箱',8);

?

select * from Categories

SELECT parentId FROM Categories WHERE parentId>0 Group By parentId Order By parentId

?

可能有人對ExtJS中樹的節點屬性不是很了解,所以我們要啰嗦一下。ExtJS只要求返回的數據格式類似下面這樣即可:
[{'text':'welcome.html','id':'welcome.html','cls':'file',myPara:'myValue'},
{'text':'welcome2.html','id':'welcome2.html','leaf':true,'cls':'file','href':'welcome2.html'}]
這些數據是存儲到一個數組中的,數組中的每一項代表一個節點,每一個節點都包含以下幾個主要屬性
:
text:
定義該節點顯示的名稱
;
id:
定義該節點的頁面ID,便于document.getElementById方法獲取該節點
;
leaf:true
或者false,定義該節點是否是葉子節點
;
cls:
定義該節點的class(顯示的樣式
);
href:
定義點擊該節點后鏈接的頁面
;
另外你還可以為節點增加自定義的屬性,方法如上面的myPara:'myValue'一樣。ExtJS會自動將返回的數據解析成節點并正確顯示到頁面上。

?

好啦,今天我們TreePanel的學習就到這里,下次我們會學習FormPanel。祝愿大家學有所成。

?

轉載于:https://www.cnblogs.com/CharmingDang/archive/2008/10/19/9663751.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的ExtJS专题-TreePanel(1)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。