Extjs TreePanel示例

转自:http://legend2011.blog.51cto.com/3018495/1171733

 这几天用到了Extjs的TreePanel来创建树形菜单,在网上没瞧见一个好的示例,遂决定写一个,供后来者参考(本文下方的“附件下载”可下载本示例的完整源代码)。

      先创建一个雏形,代码如下:

  1. var tree = new Ext.tree.TreePanel({  
  2.        title : '主菜单',  
  3.        width : 200,  
  4.        autoScroll : true,  
  5.        singleExpand : true,  
  6.        rootVisible : true,  
  7.        animate : true,  
  8.        //树加载器  
  9.        loader : new Ext.tree.TreeLoader({  
  10.           dataUrl : 'tree/treeNodeAction_listTree.action' 
  11.               })  
  12.     });  
(代码1)
      注意这里使用了一个loader属性,其值为一个Ext.tree.TreeLoader对象。根据它的名字,我们就能推测出这个对象是用来加载树的,而其dataUrl属性则指定应从何处加载树的结点信息。

      紧接着创建根节点,并将此根结点设置为树的根:

  1. var root = new Ext.tree.AsyncTreeNode({  
  2.               id : 'root',  
  3.               text : '根',  
  4.               expanded : true 
  5.            });  
  6. //将此根结点设置为树的根  
  7. tree.setRootNode(root); 

(代码2)

      这里注意以下几点:

      1、AsyncTreeNode是一种异步加载的结点,即每次只加载本结点的直接子结点,而子结点的子结点(即当前结点的孙子结点)则在需要的时候再加载,这就提高了响应速度;

      2、AsyncTreeNode也有loader属性,它的值继承自TreePanel中的loader属性(见代码1)。根结点使用此loader来加载它的子结点信息并创建子结点,而子节点也是AsyncTreeNode对象,它们的loader属性值也来自TreePanel的loader属性,它们也将使用此loader来加载自己的子结点信息,以此类推;

      3、后台发送来的代表子结点信息的JSON字符串必须以方括号“[]”包含,如本例加载根节点的子结点信息的JSON字符串如下:

[{id:'module1',text:'模块1',leaf:false},{id:'module2',text:'模块2',leaf:true,url:'demo/module2.jsp'}]

(代码3)

      加载效果如下图所示:

Extjs TreePanel示例_第1张图片

(图1:主菜单截图)

      4、当加载结点的子结点时,会向后台传送一个node参数,值为当前结点的id。如加载根节点的子节点时,会把根节点的id值“root”(见代码2的根节点的id属性)传到后台,FireBug的截图如下:

Extjs TreePanel示例_第2张图片

(图2:node参数截图)

      这样,后台就会从数据库中读取那些父结点的id为node值的结点信息,即当前结点的子结点信息。这样,本示例的结点信息在数据库表中的形式就如下图所示:

(图3:表中的结点信息)

      注意观察parent_id值为root的两个结点,即为图1主菜单截图中的根结点的两个子结点。

      同理,后台向前台发送结点信息时,也应该提供该结点的id值(参见代码3的JSON字符串),供将来加载此结点的子结点时使用。

      到目前为止,我们已经成功生成了树,并可以动态加载其结点信息。但我们最终的目标应该是点击TreePanel(一般放置于页面的左边)的某个叶子结点时,能在页面右部显示相关的功能页面。为了实现这个功能,应该使用Viewport,其布局为border。然后将TreePanel放置于Viewport的西区,再新建一个TabPanel,放置于Viewport的中央区。为TreePanel添加click事件处理函数,在这个函数中,若相关的页面没有被加载,则新建一个Panel加载此页面,并添加到TabPanel中,然后设置此Panel为活动的,显示给用户;若相关页面已被加载,则直接设置其为活动的即可。具体代码如下所示(注意:其中的center即为位于中央区的TabPanel):

  1. listeners : {  
  2.           click : function(node) {  
  3.              // node代表被点击的结点,通过其attributes属性读取  
  4.              // 后台传来的url等属性,url指该结点指向的页面  
  5.              var url = node.attributes.url;  
  6.              var id = node.attributes.id;  
  7.              // 从center中获取相关的Panel  
  8.              var tab = center.getItem('tab_' + id);  
  9.              // 只有当url存在,才进行后续处理  
  10.              if (url) {  
  11.                  // 如果相关的Panel已存在,直接将其设置为活动的即可  
  12.                  if (tab) {  
  13.                     center.setActiveTab(tab);  
  14.                  } else {  
  15.                     // 否则创建一个Panel,用于加载url指向的页面,然后  
  16.                     // 将此Panel添加到center中,并设置其为活动的  
  17.                     tab = new Ext.Panel({  
  18.                         title : node.attributes.text,  
  19.                         html : "<iframe src=\'#\'" /span> 
  20.                                + url  
  21.                                + "'" 
  22.                                + " width='100%' height='100%' frameborder='0' scrolling='auto'>" 
  23.                                + "</ifame>",  
  24.                         closable : true,  
  25.                         layout : 'fit',  
  26.                         frame : false,  
  27.                         id : 'tab_' + id  
  28.                     });  
  29.                     center.add(tab);  
  30.                     center.setActiveTab(tab);  
  31.                  }  
  32.              }  
  33.           }  
  34.       } 

(代码4)

      需要注意的是,只有叶子结点才有url属性,这一点从代码3的JSON字符串即可看出:id为module1的结点为非叶子结点,因而后台并没有给它传递url信息;而id为module2的结点为叶子结点,就有url属性。

      效果如图所示(本示例的完整源代码请于本文下方的“附件下载”处下载):

Extjs TreePanel示例_第3张图片 

本文出自 “肖凡的专栏” 博客,请务必保留此出处http://legend2011.blog.51cto.com/3018495/1171733

你可能感兴趣的:(TreePanel)