动态加载树
对于http://www.dojochina.com/?q=node/578对ExtJs动态加载树,现在给出.net版本。首先数据库结构表一样。这里我用的是sqlserver 2000 DDL如下:
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[FK_LoadTree_LoadTree]') and OBJECTPROPERTY(id, N'IsForeignKey') = 1)
ALTER TABLE [dbo].[LoadTree] DROP CONSTRAINT FK_LoadTree_LoadTree
GO
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[LoadTree]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [dbo].[LoadTree]
GO
CREATE TABLE [dbo].[LoadTree] (
[ItemID] [int] NOT NULL ,
[ItemName] [varchar] (20) COLLATE Chinese_PRC_CI_AS NULL ,
[ParentID] [int] NOT NULL ,
[IsAvailable] [int] NULL
) ON [PRIMARY]
GO
在Ext中 Tree.AsyncTreeNode实现对树结点的异步加载。此时我们只需让服务端生成指定格式的Json字符串(格式可参看Ext的例子)。js代码依然是惯例,这里我还是把他贴出来。
{
var Tree=Ext.tree;
var tree = new Tree.TreePanel( {
el : 'tree-div',//目标div容器
autoScroll : true,
animate : true,
enableDD : true,
containerScroll : true,
loader : new Tree.TreeLoader( {
dataUrl : 'TreeJsonData.aspx '// 动态载入数据的请求地址
})
});
var root = new Tree.AsyncTreeNode( {
text : '教考分离系统',
draggable : false,
id : '-1'//这是post给服务端的。一般为root的id
});
tree.setRootNode(root);
tree.render();
root.expand();
// root.expandChildNodes();
});
下面就是服务端的事。个人认为可以用sql语句递归查处。再生成json应该会更简单,但我sql还没写出来。所以我是先全部读到datatable中,在datatable中进行的各种处理。下面为服务端完整代码:
{
//StringBuilder strTreeJson = new StringBuilder();
protected void Page_Load(object sender, EventArgs e)
{
try
{
//throw new Exception();
int rootid = int.Parse(Request.Form["node"]);
DataTable dt = DBHelper.GetAllTree();
// string treeJson = JSONHelper.ToJSON(dt, dt.Rows.Count, null);
// Response.Write(treeJson);
// Response.Write("["+GetNodeString(dt, -1)+"]");
Response.Write(GetSigleNodeString(dt, rootid));
}
catch
{
Response.Write("[{ id:100,text :\" Sorry! 没有任何节点\",leaf:true }]");
}
}
/// <summary>
/// 得到适合Ext.Tree.TreeLoader的json字符串(包含根结点)适合有多个根结点的情况
/// </summary>
/// <param name="dt">包含了所有树形结构数据的DataTable</param>
/// <param name="parentid">开始往下搜索的id</param>
/// <returns>json</returns>
private string GetNodeString(DataTable dt, int parentid)
{
DataRow[] drs = dt.Select("ItemId = " + parentid.ToString());
StringBuilder strTreeJson = new StringBuilder();
if (drs.Equals(null))
{
//return "[{ id:" + parentid.ToString() + ",text : 没有任何节点,leaf:true }]";
return null;
}
else
{
foreach (DataRow dr in drs)
{
string tempid=dr["ItemId"].ToString();
strTreeJson.Append("{ ");
strTreeJson.Append(" id :\'" +tempid + "\', text : \'" + dr["ItemName"].ToString()+"\',");
ArrayList arr = null;
if (HasChild(dt, tempid,out arr))
{
strTreeJson.Append("children : [");
for (int i = 0; i < arr.Count; i++)
{
if (i == arr.Count - 1)
{
strTreeJson.Append(GetNodeString(dt, int.Parse(arr[i].ToString())));
}
else
{
strTreeJson.Append(GetNodeString(dt, int.Parse(arr[i].ToString())));
strTreeJson.Append(",");
}
}
strTreeJson.Append("]");
strTreeJson.Append("}");
}
else
{
strTreeJson.Append("leaf : true }");
}
// strTreeJson.Append(",");
}
}
return strTreeJson.ToString();
}
/// <summary>
/// 得到适合Ext.Tree.TreeLoader的json字符串适合有单个根结点的情况
/// </summary>
/// <param name="dt"></param>
/// <param name="parentId"></param>
/// <returns></returns>
private string GetSigleNodeString(DataTable dt, int parentId)
{
DataRow[] singledr = dt.Select("ItemId = " + parentId.ToString());
StringBuilder singleTreeJson= new StringBuilder();
if (singledr.Length > 1)
{
throw new Exception("给定parentId包含多个结点请使用GetNodeString()方法");
}
else if (singledr.Equals(null))
{
return null;
}
else
{
DataRow[] dr = dt.Select("ParentId = " + parentId.ToString()+ "and ParentId<>ItemId");
singleTreeJson.Append("[");
for (int i = 0; i < dr.Length; i++)
{ int j=int.Parse(dr[i]["ItemId"].ToString());
if (i == dr.Length - 1)
{
singleTreeJson.Append(GetNodeString(dt, j));
}
else
{
singleTreeJson.Append(GetNodeString(dt, j));
singleTreeJson.Append(",");
}
}
singleTreeJson.Append("]");
return singleTreeJson.ToString();
}
}
/// <summary>
/// 给定id判断是否含有子节点及输出的包含所有子节点的id的ArrayList
/// </summary>
/// <param name="dt"></param>
/// <param name="id"></param>
/// <param name="childid"></param>
/// <returns></returns>
private bool HasChild(DataTable dt, string id,out ArrayList childid)
{
DataRow[] dr= dt.Select("ParentId =" +id +"and ItemId<>ParentId " );
childid = new ArrayList();
if (dr.Length == 0)
{
childid = null;
return false;
}
else
{
for (int i = 0; i < dr.Length; i++)
{
childid.Add(dr[i]["ItemId"]);
}
return true;
}
}
}
看看效果,呵呵!!!Ok