树型控件
(1) TreePanel
在应用程序中,我们经常会涉及到要显示或处理树状结构的对象信息,比如部门信息、地区信息,或者是树状的菜单信息,操作系统中的文件夹信息等。对于传统的html 页面来说,要自己实现显示树比较困难,需要写很多的javascript,特别是对于基于Ajax 异步加载的树来说,不但涉及到Ajax 数据加载及处理技术,还需要考虑跨浏览器支持等,处理起来非常麻烦。ExtJS 中提供了现存的树控件,通过这些控件可以在B/S 应用中快速开发出包含树结构信息的应用。
TreePanel基本使用
树控件由Ext.tree.TreePanel 类定义,控件的名称为treepanel,TreePanel 类继承自Panel面板。在ExtJS 中使用树控件其实非常简单,我们先来看下面的代码:
Ext.onReady(function(){
var root=new Ext.tree.TreeNode({id:"root",text:"树的根"});
root.appendChild(new Ext.tree.TreeNode({id:"c1",text:"子节点"}));
var tree=new Ext.tree.TreePanel({renderTo:"mydiv",root:root,width:100});
});
代码的第一句使用new Ext.tree.TreeNode 类来创建一个树节点,第二句使用树节点的root 的appendChild 方法来往该节点中加入一个子节点,最后直接使用new Ext.tree.TreePanel来创建一个树面板,要树面板的初始化参数中指定树的root 属性值为前面创建的root 节点,也就是树根节点。
树的节点信息。ExtJS 的树控件提供了对这种功能的支持,你只需要在创建树控件的时候,通过给树指定一个节点加载器,可以用来从服务器端动态加载树的节点信息。我们来看下面的代码:
treedata.js文件用来存放节点信息:
[{
id: 1,
text: '节点1',
leaf: true
},{
id: 2,
text: '节点2',
children: [{
id: 3,
text: '节点21',
leaf: true
}]
}]
注意:treedata.js文件中如果有中文,需要修改js文件的编码(在ecliipse中),建议使用UTF-8编码。
下面通过加载treedata.js文件构造树:
Ext.onReady(function(){
var root=new Ext.tree.AsyncTreeNode({id:"root",text:"根节点"});
var tree=new Ext.tree.TreePanel({
renderTo:"mydiv",
root:root,
loader: new Ext.tree.TreeLoader({url:"treedata.js"}),
width:300,
height:200
});
});
<div id=”mydiv”></div>
执行上面的程序,可以得到一棵异步加载子节点的树,点击“根节点”会到服务器端加载子节点。
事件处理
仅仅能显示一棵树还不够,我们一般还需要在用户点击树节点的时候执行相应的东西,比如打开某一个连接,执行某一个函数等,这就需要使用到事件处理。比如下面的代码:
Ext.onReady(function(){
var root=new Ext.tree.TreeNode({
id:"root",
text:"树根"});
var c1=new Ext.tree.TreeNode({
id:"c1",
text:"子节点"
});
root.appendChild(c1);
var tree=new Ext.tree.TreePanel({
renderTo:"mydiv",
root:root,
width:100
});
//给树添加事件
tree.on("click",function(node,event){
alert("您点击了"+node.text);
});
//给c1节点添加事件
c1.on("click",function(node,event){
alert("您点击了"+node.text);
});
});
<div id=”mydiv”></div>
执行上面的程序,当用户点击树控件中的任意节点时,都会弹出一个提示信息框,当用户点击c1 这个子节点时,会弹出两次提示信息框。因为我们除了指定tree 的click 事件响应函数以外,另外又给node 节点指定单独的事件响应函数。
如果只是要实现当点击树节点时跳到某一个指定url 的功能则非常简单。看下面的代码:
Ext.onReady(function(){
var root=new Ext.tree.TreeNode({
id:"root",
href:"http://www.extjs.com",
hrefTarget:"_blank",
text:"树根"
});
var c1=new Ext.tree.TreeNode({
id:"c1",
href:"http://www.iteye.com",
hrefTarget:"_blank",
text:"子节点"
});
root.appendChild(c1);
var tree=new Ext.tree.TreePanel({
renderTo:"mydiv",
root:root,
width:100
});
});
<div id=”mydiv”></div>
点击树节点,将会在浏览新窗口中打开节点中href 指定的链接。
(2) TreeNode
在ExtJS 中,不管是叶子节点还是非叶子节点,都统一用TreeNode 表表示树的节点。在ExtJS 中,有两种类型的树节点。一种节点是普通的简单树节点,由Ext.tree.TreeNode 定义,另外一种是需要异步加载子节点信息的树节点,该类由Ext.tree.AsyncTreeNode 定义。
看下面的代码:
Ext.onReady(function(){
var tree=new Ext.tree.TreePanel({
renderTo:"mydiv",
root:new Ext.tree.AsyncTreeNode({
text:"根节点"
}),
width:100
});
});
<div id=”mydiv”></div>
执行程序,点击树中的“根节点”则会一直发现树会尝试加载这个节点的子节点,由这里没有指定树的加载器,所以“根节点”会变成一直处于加载的状态。
对于普通的TreeNode 来说,可以通过调用节点的appendChild、removeChild 等方法来往该节点中加入子节点或删除子节点等操作。
TreeNode 与AsyncTreeNode 可以同时使用,比如下面的代码:
Ext.onReady(function(){
var root=new Ext.tree.TreeNode({
id:"root",
text:"树根"
});
var c1=new Ext.tree.TreeNode({
text:"node1"
})
var c2=new Ext.tree.AsyncTreeNode({
text:"node2"
});
root.appendChild(c1);
root.appendChild(c2);
var tree=new Ext.tree.TreePanel({
renderTo:"mydiv",
root:root,
width:300,
loader:new Ext.tree.TreeLoader({
url:"treedata.js"
})
});
});
treedata.js请参考之前的内容。
另外要在树以外的程序中得到当前选择的节点,可以通过TreePanel 的getSelectionModel 方法来获得,该方法默认返回的是Ext.tree.DefaultSelectionModel 对象,DefaultSelectionModel 的getSelectedNode 方法返回当前选择的树节点。比如要得到树tree 中中当前选择节点,代码如下:
Ext.onReady(function(){
var root=new Ext.tree.TreeNode({
id:"root",
text:"树根"
});
var c1=new Ext.tree.TreeNode({
text:"子节点1"
});
var c2=new Ext.tree.AsyncTreeNode({
text:"子节点2"
});
root.appendChild(c1);
root.appendChild(c2);
var tree=new Ext.tree.TreePanel({
renderTo:"mydiv",
root:root,
width:300,
loader:new Ext.tree.TreeLoader({
url:"ext-2.0/treedata.js"
})
});
Ext.get("btn").on("click",function(node,event){
alert(tree.getSelectionModel().getSelectedNode().text);
});
});
<div id="mydiv"></div>
<br/>
<input type="button" id="btn" value="获取当前选中的节点"/>
(3) TreeLoader
对于ExtJS 中的树来说,树加载器TreeLoader 是一个比较关键的部件,树加载器由Ext.tree.TreeLoader 类定义,只有AsyncTreeNode 才会使用TreeLoader。看下面的代码:
Ext.onReady(function(){
var loader=new Ext.tree.TreeLoader({
url:"treedata.js"
});
var root=new Ext.tree.AsyncTreeNode({
id:"root",
text:"根节点",
loader:loader
});
var tree=new Ext.tree.TreePanel({
renderTo:"mydiv",
root:root,
width:100
});
});
首先我们使用Ext.tree.TreeLoader 来初始化了一个TreeLoader 对象,构造函数中的配置参数url 表示获得树节点信息的url 。然后在初始化根节点的时候我们使用的是AsyncTreeNode,在该节点中指定该节点的laoder 为前面定义的loader。执行这段程序,在点击“根节点”时,会从服务器端指定root 节点的子节点信息。