Step by step asp.net ajax category Tree Generation

Source: Internet
Author: User


Although the multi-level problem of categories has brought about endless consequences .............

Recursive queries are no different from SQL statements executed by nested loops ......

This brings about serious performance problems ..

Now, I have come up with two solutions, the first one:

For the multi-level menu with few data, we can query all records at a time through the database, and then use the program for recursive algorithm to convert the data.

Second:

It is designed as a multi-level menu during database design. Each time the menu is loaded, it is expanded through ajax and 1.1 points (each expansion requests the next level of data ), this avoids performance loss caused by recursion and is easy to implement. It is very suitable for large data volumes. However, only one level can be displayed at a time, and ajax requests must be requested to the next level at a time.

As a result of background management, the first solution was designed as follows:

First, you must design the database to facilitate the expansion in the next two ways,

The FId field is designed to facilitate the expansion of the front-end and back-end. The advantage of this design is that if you query all products under top-level menus, all products can be queried by fuzzy search prefix matching. The design field is still a little small. IsLeaf is used to determine whether it is a leaf node and the BelongSid parent level id,

Front-end code:
Copy codeThe Code is as follows:
<! 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> product category management </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. 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> product category management <Div class = "mini-panel" title = "Product Category Management" 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"> mobile node </li> -->
<Li class = "separator"> </li>
<Li name = "addNode" onclick = "onAddNode" iconCls = "icon-add"> insert a node </li>
<Li name = "edit" iconCls = "icon-edit" onclick = "onEditNode"> edit a node </li>
<Li name = "remove" iconCls = "icon-remove" onclick = "onRemoveNode"> delete a node </li>
<Li name = "cancel" iconCls = "icon-cancel" onclick = "onCancel"> cancel </li>
<Li class = "separator"> </li>
</Ul>
</Div>
<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: "null", pid: node. id };
Mini. prompt ("Enter the category content:", "enter ",
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 ("added successfully! ");
TreeLoad ();
// NewNode. text = value;
// If (node! = Null ){
//
// Tree. addNode (newNode, AddType, node );
//}
}
Else
Alert ("failed to add! ");
}
});
}
Else {
NewNode. text = "null ";
}
});
}
// Refresh the tree
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 ("Enter the category content:", "enter ",
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 ("saved successfully! ");
Tree. setNodeText (node, value );
// TreeLoad ();
}
Else
Alert ("Saving failed! ");
}
});
}
});
}
Function onRemoveNode (e ){
Var tree = mini. get ("tree1 ");
Var node = tree. getSelectedNode ();
If (node ){
If (confirm ("are you sure you want to delete the selected node? ")){
// Submit it to the server
$. Ajax ({
Url: "Data/GetProductInfo. ashx ",
Type: "post ",
Data: "method = RemoveProductType & id =" + node. id,
Success: function (msg ){
If (msg ){
Tree. removeNode (node );
Alert ("deleted successfully! ");
}
Else {
Alert ("deletion failed! ");
}
}
});
}
}
}
Function onBeforeOpen (e ){
Var menu = e. sender;
Var tree = mini. get ("tree1 ");
Var node = tree. getSelectedNode ();
// If (node & node. id = "-1") {// if the root node (the total root directory, the menu is blocked)
// E. cancel = true;
//// Block the default context menu of the browser
// E.html Event. 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") {// total root directory
RemoveItem. hide ();
// MoveItem. hide ();
}
}
</Script>
</Body>
</Html>

This difficulty lies in the Recursive Generation of json data:
Obtain the json data of the Tree in BLL.
Copy codeThe Code is as follows:
/// <Summary>
/// Convert the Crafts category tree to json format
/// </Summary>
/// <Returns> </returns>
Public string craftTypeTreeToJson ()
{
// Transmitted json format
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 \ ""); // Add a parent node
Sb. Append (", expanded: \" false \"");
If (root. IsLeaf = "0") // if it is a leaf node, add children: [{xxx} recursively.
{
Sb. Append (", children :");
GetLeafTree (ref sb, (int) root. ID, craftTypeList); // recursively append a leaf
}
Sb. Append ("},");
}
}
Sb. Remove (sb. Length-1, 1); // Remove the last excess,
Sb. Append ("]");
Return Common. FormatToJson. MiniUiToJsonForTree (sb. ToString (), "Crafts category ");
}
/// <Summary>
/// Recursively retrieve json data of all classes under the parent ID
/// </Summary>
/// <Param name = "sb"> json string </param>
/// <Param name = "parentID"> parent id </param>
/// <Param name = "craftTypeList"> category information set </param>
Public void GetLeafTree (ref StringBuilder sb, int parentID, IEnumerable <crafttype> craftTypeList)
{
Sb. Append ("[");
Foreach (crafttype leaf in craftTypeList)
{
If (leaf. Belongsid = parentID) // locate the leaf based on the parent node
{
Sb. Append ("{id: \" "+ leaf. ID +" \ ", text: \" "+ leaf. Name + "\"");
Sb. Append (", pid: \" "+ parentID +" \ ""); // Add a parent node
Sb. Append (", expanded: \" false \"");
If (leaf. IsLeaf = "0") // if it is a leaf node, add children: [{xxx} recursively.
{
Sb. Append (", children :");
GetLeafTree (ref sb, (int) leaf. ID, craftTypeList); // recursively append a leaf
}
Sb. Append ("},");
}
}
Sb. Remove (sb. Length-1, 1); // Remove the last excess,
Sb. Append ("]");
}

As follows:

Although ajax is implemented, it is true that ajax loads all the data at a time, which has a serious performance loss. However, considering the background, it is not processed, however, it is best to use the second method for design. That method is the best solution and suitable for front-end data presentation.
The second method is in practice .........

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.