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