一步一步asp.net ajax类别Tree生成

一步一步asp.net ajax类别Tree生成
虽然实现了类别多级的问题这样带来的后果确实无穷无尽的.............

递归查询,和双循环嵌套的执行sql语句没什么区别了......

这样带来的是严重的性能问题..

现在重新做这些东西,我想到了2个方案,第一个:

针对数据比较少的多级菜单,我们可以通过数据库一次查询出来所有记录,然后通过程序进行递归算法,进行数据的转化.

第二种:

就是数据库设计的时候,设计成多级别的菜单,每次加载通过ajax,一点一点展开(每一次展开都ajax请求下一级的数据),这样避免的递归带来的性能损失,而且实现简单方便,非常适合大数据量的时候,但是,一次只能显示一级,每次都要ajax请求下一级.

由于后台管理,第一次就按照第一种方案来设计:

首先,要设计好数据库,方便以后两种方式扩展,
一步一步asp.net ajax类别Tree生成
这样设计,主要是考虑方便前台后台的扩展,FId字段是一个为了方便前台查询而设计的,这样设计的好处就是如果查询比如顶级菜单下的所有产品,只需要根据模糊查询前缀匹配,就能把所有的产品都查询出来,设计的字段还是有点小,IsLeaf是为了判断是否是叶子节点,BelongSid父级id,
一步一步asp.net ajax类别Tree生成
前台代码:

代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>产品类别管理</title> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8" /> 
<link href="../css/demo.css" rel="stylesheet" type="text/css" /> 
<script src="../scripts/jquery-1.6.2.min.js" type="text/javascript"></script> 
<script src="../scripts/miniui/miniui.js" type="text/javascript"></script><link href="../scripts/miniui/themes/default/miniui.css" rel="stylesheet" type="text/css" /> 
<link href="../scripts/miniui/themes/icons.css" rel="stylesheet" type="text/css" /> 
</head> 
<body> 
<div class="mini-toolbar"> 
<h1>产品类别管理</h1> 
<div class="mini-panel" title="产品类别管理" iconCls="icon-add" style="width:100%;height:500px;" 
showToolbar="true" showCollapseButton="true" showFooter="true" 
> 
<!--toolbar--> 
<div property="toolbar"> 
</div> 
<!--footer--> 
<div property="footer"> 
</div> 
<!--body--> 
<ul id="tree1" class="mini-tree" url="Data/GetProductInfo.ashx?method=GetProductType" style="width:100%;height:100%;padding:5px;" 
showTreeIcon="true" textField="text" idField="id" contextMenu="#treeMenu" 
> 
</ul> 
<ul id="treeMenu" class="mini-menu" style="display:none;" onbeforeopen="onBeforeOpen"> 
<!-- <li name="move" iconCls="icon-move" onclick="onMoveNode">移动节点</li>--> 
<li class="separator"></li> 
<li name="addNode" onclick="onAddNode" iconCls="icon-add">插入节点</li> 
<li name="edit" iconCls="icon-edit" onclick="onEditNode">编辑节点</li> 
<li name="remove" iconCls="icon-remove" onclick="onRemoveNode">删除节点</li> 
<li name="cancel" iconCls="icon-cancel" onclick="onCancel">取消</li> 
<li class="separator"></li> 
</ul> 
</div> 
<br /><br /> 
</div> 
<script type="text/javascript"> 
mini.parse(); 
var AddTpye="add"; 
function onCancel(e){ 
var tree=mini.get("tree1"); 
var node=tree.getSelectedNode(); 
tree.isExpandedNode (node); 
} 
function onAddBefore(e) { 
AddType="before"; 
AddItem(e); 
} 
function onAddAfter(e) 
{ 
AddType="after"; 
AddItem(e); 
} 
function AddItem(e) { 
var tree = mini.get("tree1"); 
var node = tree.getSelectedNode(); 
var newNode = {id:0,text:"空",pid:node.id}; 
mini.prompt("请输入类别内容:", "请输入", 
function (action, value) { 
if (action == "ok"){ 
$.ajax({ 
url:"Data/GetProductInfo.ashx", 
type:"post", 
data:"method=AddProductType&text="+value+"&pid="+node.id+"&IsLeaf="+tree.isLeaf(node), 
success:function(msg){ 
if(msg){ 
alert("添加成功!"); 
TreeLoad(); 
// newNode.text=value; 
// if(node!=null){ 
// 
// tree.addNode(newNode, AddType, node); 
// } 
} 
else 
alert("添加失败!"); 
} 
}); 
} 
else { 
newNode.text="空"; 
} 
}); 
} 
//刷新树 
function TreeLoad(){ 
$.ajax({ 
url:"Data/GetProductInfo.ashx?method=GetProductType", 
type:"json", 
success:function(json){ 
var tree = mini.get("tree1"); 
// alert(json); 
var data= eval("("+json+")"); 
tree.loadData(data); 
} 
}); 
} 
function onAddNode(e) { 
AddType="add"; 
AddItem(e); 
} 
function onEditNode(e) { 
var tree = mini.get("tree1"); 
var node = tree.getSelectedNode(); 
mini.prompt("请输入类别内容:", "请输入", 
function (action, value) { 
if (action == "ok") { 
$.ajax({ 
url:"Data/GetProductInfo.ashx", 
type:"post", 
data:"method=SaveProductType&id="+node.id+"&text="+value+"&pid="+node.pid+"&IsLeaf="+tree.isLeaf(node), 
success:function(msg){ 
if(msg){ 
alert("保存成功!"); 
tree.setNodeText(node,value); 
//TreeLoad(); 
} 
else 
alert("保存失败!"); 
} 
}); 
} 
}); 
} 
function onRemoveNode(e) { 
var tree = mini.get("tree1"); 
var node = tree.getSelectedNode(); 
if (node) { 
if (confirm("确定删除选中节点?")) { 
//这里提交到服务器 
$.ajax({ 
url:"Data/GetProductInfo.ashx", 
type:"post", 
data:"method=RemoveProductType&id="+node.id, 
success:function(msg){ 
if(msg){ 
tree.removeNode(node); 
alert("删除成功!"); 
} 
else{ 
alert("删除失败!"); 
} 
} 
}); 
} 
} 
} 
function onBeforeOpen(e) { 
var menu = e.sender; 
var tree = mini.get("tree1"); 
var node = tree.getSelectedNode(); 
// if (node && node.id == "-1") { //如果根节点(总根目录,那么阻止菜单显示) 
// e.cancel = true; 
// //阻止浏览器默认右键菜单 
// e.htmlEvent.preventDefault(); 
// return; 
// } 
//////////////////////////////// 
var editItem = mini.getbyName("edit", menu); 
var removeItem = mini.getbyName("remove", menu); 
var addNodeItem=mini.getbyName("addNode",menu); 
//var moveItem=mini.getbyName("move",menu); 
editItem.show(); 
removeItem.show(); 
addNodeItem.show(); 
if (node.id == "-1") {//总根目录 
removeItem.hide(); 
// moveItem.hide(); 
} 
} 
</script> 
</body> 
</html>

这一个难点在于json数据递归生成:
BLL中获得Tree的json数据

代码如下:

/// <summary> 
/// 工艺品类别树转化为json格式 
/// </summary> 
/// <returns></returns> 
public string craftTypeTreeToJson() 
{ 
//传递的json格式 
IEnumerable<crafttype> craftTypeList = new crafttypeDAL().ListAll(); 
StringBuilder sb = new StringBuilder("["); 
foreach (crafttype root in craftTypeList) 
{ 
if (root.Belongsid == -1) 
{ 
sb.Append("{id:\"" + root.ID + "\",text:\"" + root.Name + "\""); 
sb.Append(",pid:\"-1\"");//添加父节点 
sb.Append(",expanded:\"false\""); 
if (root.IsLeaf == "0")//如果是不是叶子节点,那么,就要递归添加children:[{xxx},内容 
{ 
sb.Append(",children:"); 
GetLeafTree(ref sb, (int)root.ID, craftTypeList);//递归追加叶子 
} 
sb.Append("},"); 
} 
} 
sb.Remove(sb.Length - 1, 1); //去除掉最后一个多余的, 
sb.Append("]"); 
return Common.FormatToJson.MiniUiToJsonForTree(sb.ToString(), "工艺品类别"); 
} 
/// <summary> 
/// 递归获得父级ID下的所有类别json数据 
/// </summary> 
/// <param name="sb">json字符串</param> 
/// <param name="parentID">父级id</param> 
/// <param name="craftTypeList">类别信息集合</param> 
public void GetLeafTree(ref StringBuilder sb,int parentID,IEnumerable<crafttype> craftTypeList) 
{ 
sb.Append("["); 
foreach (crafttype leaf in craftTypeList) 
{ 
if (leaf.Belongsid == parentID) //根据双亲节点查找叶子 
{ 
sb.Append("{id:\"" + leaf.ID + "\",text:\"" + leaf.Name + "\""); 
sb.Append(",pid:\"" + parentID + "\"");//添加父节点 
sb.Append(",expanded:\"false\""); 
if (leaf.IsLeaf == "0")//如果是不是叶子节点,那么,就要递归添加children:[{xxx},内容 
{ 
sb.Append(",children:"); 
GetLeafTree(ref sb,(int)leaf.ID, craftTypeList);//递归追加叶子 
} 
sb.Append("},"); 
} 
} 
sb.Remove(sb.Length - 1, 1); //去除掉最后一个多余的, 
sb.Append("]"); 
}

效果图如下:
一步一步asp.net ajax类别Tree生成
虽然是ajax实现,不过这个确实ajax一次性把数据全部加载进去,这样对性能有严重的损失,不过考虑是后台,所以,没做处理,不过最好还是用第二种方法设计,那种方法是最好的解决方法,也适合前台的数据展示.
第二种方法正在实践中………

相关推荐