[ExtJS2.1教程-7]Tree(树控件)

[b]树控件:
树是由根节点、叶子节点、非叶子节点(目录节点)组成的,其中根节点只有一个,叶子节点是终端节点。[/b]
ext中节点类型有普通树节点和异步加载节点(用于后台交互)
ext中提供了节点的选择模型:单选(选择一行) 多选(选择多行) 复选(通过复选框选择)
TreePanel用于呈现我们树的面板。TreeNode是树节点,AsyncTreeNode是动态加载树节点(异步树节点)。
既然我们要创建Tree,首先要创建一个根,当然ext中根节点也是节点所以统一用TreeNode进行创建。
TreeNode中text属性表示节点名称,leaf表示节点是否是叶子节点,id节点的唯一标识,href,hreftarget表示连接地址及打开方式,draggable表示拖拽,checked表示在节点前面是否展现复选框,allowChildren,allowDrag是否允许添加子节点,是否允许拖动等等。这里text,id是必须的。
我们创建好根之后,就要创建一个树面板(TreePanel)。
TreePanel中的配置选项包含root属性,根节点。renderto用于渲染的div

<body>
<div id="hello"></div>
</body>


Ext.onReady(function(){
var root = new Ext.tree.TreeNode({
id:"root",
text:"我是根"
});
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:200
});
});

[img]/upload/attachment/73629/6d2eef56-e37d-30ea-b07f-69d9387c6413.jpg[/img]
这样一颗简单的树就呈现出来了
好像太简单了 我们就想根节点添加一些节点

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:"hello",
root:root,
width:200
});
});

[img]/upload/attachment/73631/d7905b54-125f-38ec-98ac-c9f02ef07078.jpg[/img]
[img]/upload/attachment/73633/08b611c2-1e82-3083-af9e-e80feed98095.jpg[/img]
我们发现树的图标发生了改变,可以清晰的看出是否是叶子节点。
我们也可以通过leaf属性进行指定。但是这里我们即便手动定义了leaf:false也是不起作用的因为他下面没有节点。这一点与树的加载方式有关。
如果下面有子节点我们可以强制定义成true

Ext.onReady(function(){
var root = new Ext.tree.TreeNode({
id:"root",
text:"我是根"
});
root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是子节点",
leaf:false
}));
var c2 = new Ext.tree.TreeNode({
id:"c2",
text:"我是子节点2"
});
c2.appendChild(new Ext.tree.TreeNode({
id:"c21",
text:"我是子节点2的子节点"
}));
root.appendChild(c2);
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:200
});
});

[img]/upload/attachment/73639/43179137-6277-324f-82c4-2bd08423ed80.jpg[/img]


Ext.onReady(function(){
var root = new Ext.tree.TreeNode({
id:"root",
text:"我是根"
});
root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是子节点",
leaf:false
}));
var c2 = new Ext.tree.TreeNode({
id:"c2",
text:"我是子节点2",
leaf:true
});
c2.appendChild(new Ext.tree.TreeNode({
id:"c21",
text:"我是子节点2的子节点"
}));
root.appendChild(c2);
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:200
});
});

[img]/upload/attachment/73641/4c50d9a0-52cd-3ef9-9351-e4377638a414.jpg[/img]
这里我们需要点击节点前面的+-进行展开收缩,
我们也可以通过直接点击节点区域进行展开或者收缩,这里可以通过TreeNode中的singleClickExpand:boolean

Ext.onReady(function(){
var root = new Ext.tree.TreeNode({
id:"root",
text:"我是根",
singleClickExpand:true
});
root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是子节点",
leaf:false
}));
var c2 = new Ext.tree.TreeNode({
id:"c2",
text:"我是子节点2"
//leaf:true
});
c2.appendChild(new Ext.tree.TreeNode({
id:"c21",
text:"我是子节点2的子节点"
}));
root.appendChild(c2);
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:200
});
});

以上内容简单介绍了一下静态树的应用,下面我们来研究一下异步加载树的应用。
这里我们要用AsyncTreeNode对TreeNode进行替换。
这里我们同样需要一个根,不过这里的根节点我们使用了AsyncTreeNode异步加载树节点。
AsyncTreeNode是继承于TreeNode。loader是他自己对于TreeNode的扩展,同样我们可以按TreeNode的方式进行添加

Ext.onReady(function(){
var root = new Ext.tree.AsyncTreeNode({
id:"root",
text:"异步树的根"
});
root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是子节点",
leaf:false
}));
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:200
});
});

不同的是当我们展开根之后,根节点前的图标显示一直在加载的状态
[img]/upload/attachment/73645/955f3c0d-6f40-3cd3-9385-c667bc368ad6.jpg[/img]
这是因为他是一个异步的节点,所以一定要有一个加载器进行数据加载来完成他的功能。
这里就用到AsyncTreeNode独有的属性loader:TreeLoader。
我们要指定一个TreeLoader来完成异步加载的数据。
Ext.tree.TreeLoader中的配置选项包括url,dataurl
实际上只需返回一个json字符串就可以了。

[{
id:"c1",
text:"子节点"
},{
id:"c2",
text:"子节点2"
}]

Ext.onReady(function(){
var root = new Ext.tree.AsyncTreeNode({
id:"root",
text:"异步树的根",
loader:new Ext.tree.TreeLoader({
url:"treedata.js"
})
});
root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是子节点",
leaf:false
}));
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:200
});
});

这里的url是现对于引用界面的相对路径
[img]/upload/attachment/73648/191fb422-95e0-3c88-8ca3-17e3eab7af99.jpg[/img]
我们可以看到当使用loader之后原

root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是子节点",
leaf:false
}));
将不起作用。
这里我们发现树竟然展不完,竟然是一个无限循环。

由于我们的json数据中没有指定他是叶子节点,所以当再次点击的时候他又会重新加载,并将数据挂在当前节点下面。
根本原因在于我们将loader放置在root下面,等同于将它放置在treePanel下面

Ext.onReady(function(){
var root = new Ext.tree.AsyncTreeNode({
id:"root",
text:"异步树的根"
});
root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是子节点",
leaf:false
}));
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:200,
loader:new Ext.tree.TreeLoader({
url:"treedata.js"
})
});
});


[{
id:"c1",
text:"子节点",
leaf:true
},{
id:"c2",
text:"子节点2"
}]

实际上loader的放置位置与实际的呈现效果会有一些区别。
这里我们间静态树节点和异步节点结合起来看看

Ext.onReady(function(){
var root = new Ext.tree.TreeNode({
id:"root",
text:"异步树的根"
});
root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是子节点",
leaf:false
}));
var c2 = new Ext.tree.AsyncTreeNode({
id:"c2",
text:"我是子节点2",
loader:new Ext.tree.TreeLoader({
url:"treedata.js"
})
});
root.appendChild(c2);
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:200

});
});


[{
id:"c1",
text:"子节点21",
leaf:true
},{
id:"c2",
text:"子节点22"
}]

[img]/upload/attachment/73661/8963bc53-6e70-3508-8969-5866768ec601.jpg[/img]
我们将root换成静态节点,这样就不存在root展开时的加载问题

总结:我们在使用AsyncTree的时候需要引入加载器,加载器中的返回的数据是json类型的字符串

节点选择模型
我们首先看一下我们的简单树

Ext.onReady(function(){

var root = new Ext.tree.TreeNode({
id:"root",
text:"我是根"
});

root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是节点1"
}));

root.appendChild(new Ext.tree.TreeNode({
id:"c2",
text:"我是节点2"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c3",
text:"我是节点3"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c4",
text:"我是节点4"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c5",
text:"我是节点5"
}));
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:300
});
});

[img]/upload/attachment/74282/fdff0130-f0be-3fd1-9388-8b27ab40bb6b.jpg[/img]
该树不能选择多行(无论是使用shift ctrl都不可以)
在树的选择模型上存在DefaultSelectionModel和MultiSelectionModel两个模型选择器。
TreePanel可以通过getSelectionModel可以获得选择模型。默认使用DefaultSelect
不过可以通过配置选项的selModel来设置选择模型
我们通过一个例子看一下选择模型的使用


Ext.onReady(function(){

var root = new Ext.tree.TreeNode({
id:"root",
text:"我是根"
});

root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是节点1"
}));

root.appendChild(new Ext.tree.TreeNode({
id:"c2",
text:"我是节点2"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c3",
text:"我是节点3"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c4",
text:"我是节点4"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c5",
text:"我是节点5"
}));
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
root:root,
width:300,
tbar:[{
text:"查看",
pressed:true,
handler:showSelected
}]
});
function showSelected(){
var node = tree.getSelectionModel().getSelectedNode();
if(node){
alert(node.text);
}
}
});

他将alert出我们所选节点的text属性
[img]/upload/attachment/74286/5dce0bd4-304a-3151-8a6d-4fc53e7ee9e9.jpg[/img]

我们来看一看如何使用多选的模型选择器


Ext.onReady(function(){

var root = new Ext.tree.TreeNode({
id:"root",
text:"我是多选根"
});

root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是节点1"
}));

root.appendChild(new Ext.tree.TreeNode({
id:"c2",
text:"我是节点2"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c3",
text:"我是节点3"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c4",
text:"我是节点4"
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c5",
text:"我是节点5"
}));
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
title:"多选树模型",
root:root,
width:300,
selModel:new Ext.tree.MultiSelectionModel(),
tbar:[{
text:"查看",
pressed:true,
handler:showSelected
}]
});
function showSelected(){
var nodes = tree.getSelectionModel().getSelectedNodes();
if(nodes && nodes.length){
alert("选择:"+nodes.length+"个");
}
}
});

这里我们可以通过ctrl进行多行选中
[img]/upload/attachment/74318/af8708f2-cf27-3ca4-b137-9f46744a71cd.jpg[/img]
我们可以通过TreeNode的checked配置选项设置复选,并且可以通过TreePanel的getChecked()方法得到被选中节点的数组。


Ext.onReady(function(){

var root = new Ext.tree.TreeNode({
id:"root",
text:"我是复选根",
checked:false
});

root.appendChild(new Ext.tree.TreeNode({
id:"c1",
text:"我是节点1",
checked:true
}));

root.appendChild(new Ext.tree.TreeNode({
id:"c2",
text:"我是节点2",
checked:true
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c3",
text:"我是节点3",
checked:true
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c4",
text:"我是节点4",
checked:true
}));
root.appendChild(new Ext.tree.TreeNode({
id:"c5",
text:"我是节点5",
checked:false
}));
var tree = new Ext.tree.TreePanel({
renderTo:"hello",
title:"复选树模型",
root:root,
width:300,
tbar:[{
text:"查看",
pressed:true,
handler:showSelected
}]
});
function showSelected(){
var nodes = tree.getChecked();
if(nodes && nodes.length){
alert("选择:"+nodes.length+"个");
}
}
});

[img]/upload/attachment/74334/18964215-a21a-36b2-bb21-29dc83735d69.jpg[/img]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值