ExtJs之TreePanel篇

ExtJs系列的东西好久没有写了(最初想一气呵成的,可是中间有些工作,就给耽误了),今天我们继续看Ext中的TreePanel。有人说即使为了"树"也要学习Ext,足见"树"在Ext中是何等的重要。事实上也确实如此,在Ext中使用"树"可以像在WinFrom中一样操作树形结构。

静态树

现在我们先看看Ext中最简单的静态树。

<html> <head> <link href="ext/resources/css/ext-all.css" mce_href="ext/resources/css/ext-all.css" rel="stylesheet" type="text/css" /> <mce:script src="ext/adapter/ext/ext-base.js" mce_src="ext/adapter/ext/ext-base.js" type="text/javascript"></mce:script> <mce:script src="ext/ext-all.js" mce_src="ext/ext-all.js" type="text/javascript"></mce:script> <mce:script type="text/javascript"><!-- Ext.onReady(function(){ var tp=new Ext.tree.TreePanel({ //el:"divTreePanelContent",//应用到的html元素id animate:true,//以动画形式伸展,收缩子节点 //frame:true, title:"Extjs TreePanel", //enableDrag:true,//节点能否拖动 //collapsible:true, rootVisible:true,//是否显示根节点 autoScroll:true, autoHeight:true, autoWidth:true, border:false, useArrows:false,//是否显示小箭头 //trackMouseOver:false,//鼠标放上去效果 //lines:true,//节点之间虚线 loader:new Ext.tree.TreeLoader(),//加载节点数据 root:new Ext.tree.AsyncTreeNode({ id:"root", text:"所有商品种类",//节点名称 singleClickExpand:true,//是否单击展开,否则双击展开 expanded:true,//展开 //href:"http:/www.cmj.com", //hrefTarget:"_blank",//超链接打开的目标 checked:false,//是否显示checkbox leaf:false,//是否为叶子节点 children:[ {id:"Beverages",text:"Beverages",children:[{text:"Chai",leaf:true},{text:"Chang",leaf:true}]}, {id:"Condiments",text:"Condiments",children:[{text:"Aniseed Syrup",leaf:true},{text:"Chef Anton's Cajun Seasoning",leaf:true},{text:"Chef Anton's Gumbo Mix",leaf:true}]} ] }) }); var pnNorth=new Ext.Panel({ id:'pnNorth', autoWidth:true, heigth:80, frame:true, region:'north', html:'这里放置页头内容' }); var pnWest=new Ext.Panel({ id:'pnWest', title:'菜单项', width:200, heigth:'auto', split:true,//显示分隔条 region:'west', collapsible:true, items:[ tp ] }); var pnCenter=new Ext.TabPanel({ region:'center', activeTab:0, items:[ { title:'商品信息', authHeight:true, closable:true,//是否可关闭 html:'这里显示商品信息。。。' } ] }); var vp=new Ext.Viewport({ layout:"border", items:[ pnNorth, pnWest, pnCenter ] }); }); // --></mce:script> </head> <body> <div id="divTreePanel"></div> <div id="divTreePanelContent" style="display:none" mce_style="display:none"> ExtJs学习,欢迎大家多多交流,共同进步!cmj studio! </div> </body> </html>  

看一下效果。

ExtJs之TreePanel篇_第1张图片

上面我基本上对每个配置属性进行了说明,值得注意的就是loader配置属性,它的功能就是加载数据,虽然从上面还看不到它的作用(因为我们的是静态树,数据直接写在了root中),不过后面我们就会看到它的作用。接着就是AsyncTreeNode,从字面可以看出它是一个异步节点,也就是说它的数据是通过异步加载的(注意这里的异步指的是Ajax方式加载,是树级别的。后面的章节中我们会说节点级别的异步加载,可以点击某个节点就只加载它下面的节点其它节点不加载)。最后我觉得要注意的就是节点的结构,我们虽然这里是静态构造的,后面我们的动态树在构造的时候也是这样的结构。

动态树

静态树简单但是却不太实用,实际开发过程中更多的还是动态树,下面我们就一块看一下动态树的使用,这里再明确说明一下,我这里不仅仅"树"的数据是动态从后台获取的,而且还可以根据条件显示不同的"树"结构,这也是很多朋友经常遇到的情况,所以直接在这个例子里给出。注意这里传参的方式,我注释的很清楚,很多朋友之所以不会做不是因为别的就是因为不会传参。

前台代码

<html> <head> <link href="ext/resources/css/ext-all.css" mce_href="ext/resources/css/ext-all.css" rel="stylesheet" type="text/css" /> <mce:script src="ext/adapter/ext/ext-base.js" mce_src="ext/adapter/ext/ext-base.js" type="text/javascript"></mce:script> <mce:script src="ext/ext-all.js" mce_src="ext/ext-all.js" type="text/javascript"></mce:script> <mce:script type="text/javascript"><!-- Ext.onReady(function(){ var tb=new Ext.Toolbar({ id:'tbSupplier' }); var tf=new Ext.form.TextField({id:'supplierName',name:'supplierName',value:''}); tb.addText("供货商名称:"); tb.addField(tf); tb.addSpacer(); tb.addButton({text:'查询',handler:function(){//点击按钮重新加载树,此时会触发beforeload事件,因此也就将参数传递进去了 tp.root.reload(); }}); var tl=new Ext.tree.TreeLoader({ }); var tp=new Ext.tree.TreePanel({ //el:"divTreePanelContent",//应用到的html元素id animate:true,//以动画形式伸展,收缩子节点 //frame:true, //title:"Extjs TreePanel", //enableDrag:true,//节点能否拖动 //collapsible:true, rootVisible:true,//是否显示根节点 autoScroll:true, autoHeight:true, autoWidth:true, border:false, useArrows:false,//是否显示小箭头 //trackMouseOver:false,//鼠标放上去效果 //lines:true,//节点之间虚线 /*listeners:{//监听单击事件 "click":function(node,e){ Ext.Msg.alert("系统提示","节点ID:"+node.id+"节点Name:"+node.text); } },*/ loader:tl }); var root=new Ext.tree.AsyncTreeNode({//定义根节点 id:"root", text:"所有商品种类", expanded:true }); tp.setRootNode(root); tp.on("beforeload",function(node){//在beforeload事件中动态传递参数,对于TreePanel不能像GridPanel和ComboBox用Store的load传递参数,但是可以使用beforeload方法,而且这种方法也同样适用于前两者 //tl.dataUrl="Default.aspx?type=dynamicLoadTreePanel&supplierName="+tf.getValue();//方法一,也可以使用baseParams传递参数 tl.dataUrl="Default.aspx"; tl.baseParams.type="dynamicLoadTreePanel"; tl.baseParams.supplierName=tf.getValue(); }); var winProduct var pnNorth=new Ext.Panel({ id:'pnNorth', autoWidth:true, heigth:80, frame:true, region:'north', html:'这里放置页头内容' }); var pnWest=new Ext.Panel({ id:'pnWest', title:'菜单项', width:245, //layout:'fit', autoScroll:true, split:true,//显示分隔条 region:'west', collapsible:true, items:[ tb, tp ] }); var pnCenter=new Ext.TabPanel({ region:'center', activeTab:0, items:[ { title:'商品信息', authHeight:true, closable:true,//是否可关闭 html:'这里显示商品信息...' } ] }); var vp=new Ext.Viewport({ layout:"border", items:[ pnNorth, pnWest, pnCenter ] }); Ext.EventManager.onWindowResize(function(w,h){ tp.syncSize(); },this,true); }); // --></mce:script> <mce:style type="text/css"><!-- .mnAddProduct { background-image:url(ext/resources/images/default/tree/folder.gif) !important; } --></mce:style><style type="text/css" mce_bogus="1"> .mnAddProduct { background-image:url(ext/resources/images/default/tree/folder.gif) !important; } </style> </head> <body> <div id="divTreePanel"></div> <div id="divTreePanelContent" style="display:none" mce_style="display:none"> ExtJs学习,欢迎大家多多交流,共同进步!cmj studio! </div> </body> </html>

后台代码

using System; using System.Collections; using System.Configuration; using System.Data; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using System.Collections.Generic; using System.Web.Script.Serialization; using Cmj.MyData; namespace TreePanel { public partial class _Default : System.Web.UI.Page { DBHelper dbHelper = new DBHelper();//自定义数据库操作类,负责数据库基本操作 protected void Page_Load(object sender, EventArgs e) { string type = ""; if (!string.IsNullOrEmpty(Request["type"])) { type = Request["type"]; } if (type == "dynamicLoadTreePanel") { string supplierName=""; supplierName=Request["supplierName"]; Response.Write(GetProductBySupplier(supplierName)); } Response.Flush(); Response.End(); } /// <summary> /// 按供货商名称构造树形结构 /// </summary> /// <param name="supplierId"></param> /// <returns></returns> private string GetProductBySupplier(string supplierName) { List<Node> nodes = new List<Node>();//定义所有节点集合 string sqlCategory = "SELECT DISTINCT dbo.Categories.CategoryID,CategoryName FROM dbo.Products INNER JOIN dbo.Categories ON dbo.Products.CategoryID = dbo.Categories.CategoryID INNER JOIN dbo.Suppliers ON dbo.Products.SupplierID=dbo.Suppliers.SupplierID WHERE dbo.Suppliers.CompanyName LIKE '%"+supplierName+"%' "; DataTable dtCategory = dbHelper.GetDataTable(CommandType.Text, sqlCategory); string sqlProduct = ""; DataTable dtPorduct = null; Node nodesOne = null;//定义一级节点,显示商品种类 Node nodesTwo = null;//定义二级节点,显示商品名称 foreach (DataRow dr in dtCategory.Rows) { nodesOne = new Node(); nodesOne.id = "Category_" + dr["CategoryID"].ToString();//注意id不能够重复,否则造成折叠和展开出问题 nodesOne.text = dr["CategoryName"].ToString(); nodesOne.leaf = false;//不是叶子节点 sqlProduct = "SELECT dbo.Products.ProductID,dbo.Products.ProductName FROM dbo.Products INNER JOIN dbo.Suppliers ON dbo.Products.SupplierID = dbo.Suppliers.SupplierID WHERE dbo.Products.CategoryID='" + dr["CategoryID"].ToString() + "' AND dbo.Suppliers.CompanyName LIKE '%" + supplierName + "%'"; dtPorduct = dbHelper.GetDataTable(CommandType.Text, sqlProduct); foreach (DataRow drProduct in dtPorduct.Rows) { nodesTwo = new Node(); nodesTwo.id = "Product_" + drProduct["ProductID"].ToString(); nodesTwo.text = drProduct["ProductName"].ToString(); nodesTwo.leaf = true; nodesOne.children.Add(nodesTwo); } nodes.Add(nodesOne); } JavaScriptSerializer jsSerialier = new JavaScriptSerializer();//序列化对象 return jsSerialier.Serialize(nodes); } } }

using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml.Linq; using System.Collections.Generic; namespace TreePanel { public class Node { public string id; public string text; public bool leaf; public List<Node> children = new List<Node>(); } }

默认显示

输入条件搜索(根据供货商的公司名称,搜索出说有相关的产品)。

ExtJs之TreePanel篇_第2张图片

这里给大家提供一种构造树的简单的方法,我们知道对于树结构来说有时候父子关系不太好循环,而且要构造json,这里我们定义了一个Node类,作为一个节点它除了有id、text、leaf属性外还有children属性,而children属性是一个节点集合,这样一来我们只需要构造Node对象然后利用.Net提供的JavaScriptSerializer类进行序列化就可以了(从这也可以看出面向对象的优点)。

今天就到这里,后面我们还会继续跟大家一块学习更多关于TreePanel的东西。

你可能感兴趣的:(html,function,String,ExtJs,border,stylesheet)