Ext JS动态树实现:节点懒加载与右键菜单详解

作者:纸飞机

时间:2026-10-23

浏览:344

本文介绍如何使用Ext JS实现动态部门树,重点讲解节点懒加载机制与右键菜单功能。通过示例代码展示TreePanel配置、节点点击事件监听及Ext.menu.Menu的使用,解决子节点重复创建问题,实现按需展开与操作菜单展示。

文章目录

需求分析与核心组件

一、需求分析



系统需构建一棵部门层级树,初始状态仅显示根部门节点。


用户点击任意部门节点时,系统应动态加载该部门下的直属子部门数据,并自动展开当前被点击的节点。


部门节点需支持右键交互,当用户右键点击节点时,弹出包含相关操作项的上下文菜单。


二、核心技术组件



本实现主要依赖Ext JS框架中的以下两个核心类:



Ext.tree.TreeNode:用于表示树中的节点。


Ext.menu.Menu:用于构建和显示右键菜单。


相关API文档可参考:http://extjs.com/deploy/ext/docs/



HTML页面结构

三、代码实现示例



首先,查看测试页面的HTML结构。


HTML代码片段如下:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Reorder TreePanel</title>
<link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
<script type="text/javascript" src="../../adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="../../ext-all.js"></script>
<script type="text/javascript" src="reorder.js"></script>
<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="../shared/examples.css" />
<link rel="stylesheet" type="text/css" href="../shared/lib.css" />
<script type="text/javascript">
/************** 
onload事件
***************/ 
window.onload=function(){
createTree(3);
} 
</script>
</head>
<body>
<script type="text/javascript" src="../shared/examples.js"></script>
<h1>现在要生成一颗动态树</h1>
<div id="container">
</div>
</body>
</html>

树形面板初始化与配置

接下来,查看生成树的JavaScript函数逻辑。


JavaScript代码片段如下:

/*********************************** 
创建树
by chb
************************************/ 
function createTree(n){
Ext.QuickTips.init();
var mytree=new Ext.tree.TreePanel({
el:"container",
animate:true,
title:"Extjs动态树",
collapsible:true,
enableDD:true,
enableDrag:true,
rootVisible:true,
autoScroll:true,
autoHeight:true,
width:"30%",
lines:true
}); 
//根节点
var root=new Ext.tree.TreeNode({
id:"root",
text:"集团公司",
expanded:true
}); 
for(var i=0;i<n;i++){
var sub1=new Ext.tree.TreeNode({
id:i+1,
text:"子公司"+(i+1),
singleClickExpand:true,
listeners:{
//监听单击事件
"click":function(node){
myExpand(node);
}, 
//监听右键
"contextmenu":function(node,e){
//列出右键菜单
menu=new Ext.menu.Menu([
{ 
text:"打开当前节点",
icon:"list.gif",
handler:function(){
myExpand(node);
} 
}, 
{ 
text:"编辑当前节点",
icon:"list.gif",
handler:function(){
alert(node.id);
} 
}, 
{ 
text:"删除当前节点",
icon:"list.gif",
handler:function(){
alert(node.id);
} 
}]); 
//显示在当前位置
menu.showAt(e.getPoint());
} 
} 
}); 
root.appendChild(sub1);
} 
mytree.setRootNode(root);//设置根节点
mytree.render();//不要忘记render()下,不然不显示哦
} 

动态节点加载与交互逻辑

3. 展开子节点的代码


代码如下:

/****************************************** 
展开节点
******************************************/ 
function myExpand(node){
if(node.id=='1'){
if(node.item(0)==undefined){
node.appendChild(new Ext.tree.TreeNode({
id:node.id+'1',
text:node.text+"的第一个儿子",
hrefTarget:"mainFrame",
listeners:{//监听
"click":function(node,e){
expand2(node)
} 
} 
})); 
} 
node.expand();
}else if(node.id=='2'){
node.appendChild(new Ext.tree.TreeNode({
id:node.id+'2',
text:node.text+"的第一个儿子",
hrefTarget:"mainFrame",
listeners:{//监听
"click":function(node){
expand2(node)
} 
} 
})); 
}else{
alert(node.id+"没有子部门了");
} 
} 

读者可以自己运行一下如上代码,会发现如下现象:无论点击“子公司1”多少次,只会列出“子公司1的第一个儿子”一个节点,而每点击一次“子公司2”,就会多出一个“子公司2的第一个儿子”节点,这是为什么呢?



因为每次点击都会激发myExpand函数,而“子公司1”上加了node.item(0)==undefined的判断,这里明白了?


即:如果该部门下没有子部门,则载入子部门,否则只展开,不重新载入。


好了,就到这里吧,困了,就不详细解释了o(∩_∩)o...哈哈

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章