深入浅出ExtJS 第五章 树形结构

 5.1 TreePanel的基本使用
//树是一种非常典型的数据结构;
5.1.1 创建一棵树
//树控件有Ext.tree.TreePanel类定义,控件的名称为TreePanel;TreePanel类继承字Panel类;
Ext.onReady(function(){
var tree = new Ext.tree.TreePanel({ //创建tree对象;
store:new Ext.data.TreeStore({ //传入数据;
root:{ //root根;
text:'树根',
leaf:true
}
})
});
tree.render('tree'); //将树渲染到DOM;
}); 5.1.2 为树添加枝和叶
root:{
text:'我是根',
children:[{
text:'我是根的第一个枝子',
children:[{ //子文件夹;
text:'我是第一个枝子的第一个叶子',
leaf:true //叶子文件;
},{
text:'我是根的第一个叶子'
leaf:true
}]
}]
}
tree.getRootNode.expand(false,true);
//参数一:是否递归展开所有子节点;参数二:是否要动画效果; 5.1.3 树形的配置
//将tree期望渲染的目标id放到{}里;
renderTo:'tree' 5.1.4 使用TreeStore获得数据
//Ext.data.TreeStore可以利用从后台获取的数据为我们组装出一棵树来;只需提供数据,让TreeStore完成数据转换和装配节点
var tree = new Ext.tree.TreePanel({
store:new Ext.data.TreeStore({
proxy:{
type:'ajax',
url:'xxx.txt'
},
root:{text:'我是根'}
});
renderTo:'tree'
});
//由于异步加载会使用树形TreeStore中的url向后台发送请求;当展开节点执行对应节点的expand()方法时,它会通过Ajax访问url指定的地址并获取数据;而且还会把自己的id作为参数参数传递给url指定的地址;
//异步读取属性的节点是非常好的方法;只有点击某一节点后才会去获取子节点属性并进行渲染; 5.1.5 使用JSP提供后台数据
//当某个节点展开时,TreeStore会根据设置的url地址去后台读取数据;
//而当发动请求时,TreeStore会把这个节点的id作为参数一起发送到后台去;
//对于后台来说,只要获得node参数,就知道是哪个节点正在执行展开;
//然后后台根据节点的id返回对应的JSON数据;其中包含id(节点唯一的标识)和text(节点的名称); 5.1.6 通过XML加载树形
<nodes>
<node>
<text>node 1</text>
<leaf>false</leaf> //是树结构的文件夹;
</node>
<node>
<text>node 2</text>
<leaf>true</leaf> //是树结构的文件;
</node>
</nodes>
var store = Ext.create('Ext.data.TreeStore',{
proxy:{
type:'ajax',
url:'xx.xml',
extraParams:{
isXml:true
},
reader:{
type:'xml',
root:'nodes',
record:'node'
}
},
sorters:[{
property:'leaf',
direction:'ASC'
},{
property:'text',
direction:'ASC'
}],
root:{
text:'Ext JS',
id:'src',
expanded:true
}
});
//因为读取XML数据时Ext无法区分上下节点关联,所以想获得多级层级结构,只能通过异步方式一层一层地加载,负责输出数据的后台根据每次发送的node参数判断目前是在展开哪一个节点;
 5.2 树的事件
//使用on()把一个函数绑定到一个事件上;
tree.on('itemexpand',function(node){
console.info(node,"展开了");
});
tree.on("itmecollapse",function(node){
console.inro(node,"折叠了");
});
tree.on("itemclick",function(node){
console.info("你单击了",node);
})
 5.3 右键菜单
>1.先注册一个名为contextmenu的事件,触发事件时,弹出自己定制的菜单;
var contextmenu = new Ext.menu.Menu({
id:'theContextMenu',
items:[{
text:'点我!',
handler:function(){
alert('我被点击了~');
}
}]
});
>2.绑定contextmenu事件
tree.on('itemcontextmenu',function(view,record,item,index,e){
e.preventDefault(); //阻止浏览器默认右键;
contextmenu.showAt(e.getXY); //调用显示菜单在点击的地方;
})
 5.4 修改节点的默认图标
//每个树形节点都有icon和iconCls属性;
>.icon
{
text:'icon',
icon:'user_female.png',
leaf:true
}
>.iconCls
{
text:'iconCls',
iconCls:'icon-male',
leaf:true
}
//同时要在HTML中添加对应的CSS定义:
.x-tree-cion-leaf .icon-male {
background-image:url(user_male.png);
}
//iconCls只能定义背景图片,icon设置的是IMG的SRC部分,icon中设置的图片会把背景图片部分挡住;
 5.5 从节点弹出对话框
//从事件中获得的node只是一个对象,而不是HTML中一个实际的DOM元素;所以不能直接用animateTarget:node来实现飞出效果;
//Ext的树节点都遵循MVC设计,所以要找到对应的DOM元素,应该使用节点的View部分;
tree.on("itemclick",function(view,record,item){
Ext.Msg.show({
title:'提示',
msg:'你单击了'+record.id,
animateTarget:item //弹窗从点击点弹出;
})
});
 5.6 节点提示信息
//鼠标停留在某个节点的上方时,显示提示信息;
//在JSON中添加对应的节点提示内容,qtip:'xxx';
//此时代码需要对提示功能初始化;
 5.7 为节点设置超链接
//在节点树形中设置超链接的地址;
//在JSON数据中添加参数href:"xxx.html",打开位置hrefTarget:'_blank';
 5.8 树形的拖放
//在创建TreePanel时,设置启用插件treeviewdragdrop;从而实现叶子与树杈和根之间的拖放;
var tree = new Ext.tree.TreePanel({
viewConfig:{
plugins:{ptype:'treeviewdragdrop'} //启用拖拽插件;
},
store:new Ext.data.TreeStore({
proxy:{
type:'ajax',
url:'xxx.txt'
},
root:{text:'我是根'}
})
tree.renderTo('tree');
}); 5.8.1 节点拖放的三种形式
>1.append:放下去的节点会变成目标节点的子节点;
>2.above:放下去的节点和目标节点是兄弟关系,放下去的节点排行在前;
>3.below:放下去的节点与目标节点是兄弟关系,放下去的节点排行在后; 5.8.2 叶子拖拽问题
//Ext规定:如果节点包含leaf:true;就不能用拖放的方式添加子节点;
tree.view.on("beforedrop",function(node,data,overModel,dropPosition,dropHandler){
if(overModel.get('leaf')){ //判断鼠标指针经过的节点是否包含leaf:true;
overModel.set('leaf',false); //更改leaf属性;
overModel.set('loaded',true); //设置可以拖拽;
}
return true;
}); 5.8.3 判断拖放的目标+Ajax提交
//drop事件是拖放的节点放下去时触发的;
tree.view.on("drop",function(node,data,overModel,dropPosition,dropHandler){
//node:正在拖放的节点;
//overModel:是放下去碰到的节点;
//dropPosition:是放下去的方式;
//通过这些数据,我们可以知道当前节点的位置和状态,从而计算出数据并通过Ajax发送给后台;让后台对节点的数据进行更行;
Ext.Msg.alert("提示","咱们的节点"+node.id+"掉到了"+overModel.get('id')+"上,掉落方式是"+dropPosition);
var item = {
dropNode:node.id,
target:overModel.get('id'),
point:dropPosition
};
Ext.Ajax.request({
method:'POST',
url:'xxx.jsp',
success:function(response){
//response:相应对象;其中包含响应状态和响应内容;
Ext.Msg.alert('信息',response.responseText);
//responseText:以文本形式返回信息;
},
failure:function(){
Ext.Msg.alert("错误","与后台联系时出现问题");
},
params:{
//发送给后台的参数;"name1=value1&name2=value2";
data:encodeURIComponent(Ext.encode(item))
//对参数进行编码,避免出现非法字符;
}
});
}); 5.8.4 树之间的拖放
//对两棵树都设置ptype:'treeviewdragdrop';
 5.9 对树进行排序
//设置folderSort:true参数,可以实现为树形进行排序;
var tree = new Ext.tree.TreePanel({
store:new Ext.data.TreeStore({
folderSort:true, //为属性自动排序;
proxy:{..}
root:{...}
})
});
 5.10 带Checkbox的树形
//在节点数据设置参数:checked:true;
var tree = new Ext.tree.TreePanel({
store:new Ext.data.TreeStore({
root:{
text:'我是根',
children:[{text:'Leaf No.1',leaf:true,checked:true}]
//为叶子前添加复选框;
}
})
});
 5.11 表格与树形的结合
//在表格中实现分级显示的功能;两者都支持对不同分类数据执行展开和折叠的操作;
//通过扩展使用treecolumn插件的方式实现表格与树形结合的效果;
Ext.onReady(function(){
Ext.define('Task',{ //定义Task类;
extend:'Ext.data.Model',//继承Model类;
fields:[
{name:'task',type:'string'},
{name:'user',tyhpe:'string'},
{name:'duration',type:'string'}
]
}); var tree = new Ext.tree.TreePanel({
rootVisible:false, //隐藏根节点;
title:'示例',
renderTo:'tree',
collapsible:true, //具有可折叠功能;
useArrows:true, //在tree中使用Vista-style样式的箭头; columns:[{ //每一行应该分为激烈进行显示;
xtype:'treecolumn',
header:'任务',
width:330,
dataIndex:'task' //设置任务列;
},{
xtype:'treecolumn',
header:'持续时间',
width:100,
dataIndex:'duration'
},{
xtype:'treecolumn',
header:'负责人',
width:100,
dataIndex:'user'
}], store:new Ext.data.TreeStore({
model:Task,
proxy:{
type:'ajax', //设置Ajax方式传送;
url:'xxx.txt'
},
root:{
text:'我是根'
}
})
});
});
//后台JSON数据
[{
task:'Ext程序开发', //第一列内容;
duration:'12month', //第二列内容;
user:'', //第三列内容;
cls:'master-task', //class;
iconCls:'task-folder', //icon图标;
children:[{ //子分支;
task:'第一章内容', //分支第一行内容
duration:'1month', //分支第二行内容
user:'Lingo', //分支第三行内容
leaf:true, //叶子分支
iconCls:'tase' //icon图标
},{...}]
}]
 5.12 更多树形的高级应用
5.12.1 如何选中树的某个节点
>1.TreePanel.selectPath():传入的参数是想要选中的节点path值;
//根id='root'下有id='leaf'的节点,则selectPath('root/leaf');
>2.TreePanel.getSelectionModel():获得属性的选择模型;
//SM有一个select()函数,传入index或者节点对应的record就可以选中这个节点; 5.12.2 刷新树的所有节点
//根节点有一个reload()函数,使用它会刷其下的所有节点;若要刷新整棵树,就要取得根节点rootNode,然后调用reload()函数; 5.12.3 借用grid的缓冲视图插件
//在成千上万个树形节点需要渲染时,保证只渲染当前渲染的视图部分,自动监听滚动条的拖拽情况;按需加载,保证在显示海量数据时不发生卡顿问题;
plugins:[{ptype:'bufferedrenderer'}], //引入插件; 5.12.4 借用grid的锁定插件
//将某一列锁定,即使出现横向滚动条,也可以保证锁定的列一直显示在视图中;
//直接对某一列设置locked:true;就可以锁定它;
{
xtype:'treeecolumn',
text:'任务',
wdith:300,
dataIndex:'task',
locked:true
}
上一篇:计算城市间的球面距离(C++实现)


下一篇:TCP HTTP 详细内存分析 & time_wait setsockopt