使用递归制作仿京东淘宝的商品分类导航栏

前些天,培训ASP.NET的老师布置了作业,制作商城的一些重要功能,

昨天做了一下其中比较难的商品分类导航类,使用了递归的方法。

ps:使用的是WebForm,希望看到MVC的同学请忽略。

最终效果图:

下面记录一下:

首先是数据库部分,使用的是SQL,在一张叫做Category的表中,设置了以下字段:

[Id]  分类的Id,int,自增长
[Name]  分类的名称,nvarchar(50)
[ParentId]  父类的Id,int
[Link]  链接地址,varchar(max),用于打开链接,也可以通过Get传Id

这里只模拟了一部分数据,从85开始,有6个子类的测试数据,原本是做书店的后台数据库,但我追加了一部分数据,不影响功能的实现。

三层中的Model层,Category类:

 1 using System.Collections.Generic;
 2 
 3 namespace Cong.Model
 4 {
 5     //根节点
 6     public class Category
 7     {
 8         public int Id { get; set; }
 9 
10         public string Name { get; set; }
11 
12         public int ParentId { get; set; }
13 
14         public string Link { get; set; }
15         //子类集合 
16         public List<Category> Children { get; set; }
17 
18         public Category()
19         {
20             this.Children = new List<Category>();
21         }
22 
23         public Category(int id,string name,int parentid,string link)
24         {
25             this.Id = id;
26             this.Name = name;
27             this.ParentId = parentid;
28             this.Link = link;
29             this.Children = new List<Category>();
30         }
31     }
32 }

三层中的Dao层,CategoryDao类:

 1 using Cong.Model;
 2 using Cong.Utility;
 3 using System.Collections.Generic;
 4 using System.Data.SqlClient;
 5 
 6 namespace Cong.Dao
 7 {
 8     public class CategoryDao
 9     {
10         public IEnumerable<Category> GetAllCate()
11         {
12             string sql = "select * from Category";
13             SqlDataReader reader = SqlHelper.ExecuteReader(sql);
14             if (reader.HasRows)
15             {
16                 while (reader.Read())
17                 {
18                     Category cate=SqlHelper.MapEntity<Category>(reader);
19                     yield return cate;
20                 }
21             }
22         }
23     }
24 }

三层中的Bll层,CategoryBll类:

 1 using Cong.Dao;
 2 using Cong.Model;
 3 using System.Collections.Generic;
 4 using System.Linq;
 5 
 6 namespace Cong.Bll
 7 {
 8     public class CategoryBll
 9     {
10         CategoryDao cd = new CategoryDao();
11 
12         public Category GetCategorys()
13         {
14             List<Category> list = cd.GetAllCate().ToList();
15 
16             Category root = new Category();
17             //为节点对象root添加子类,主要是parentId为0的对象
18             root.Children.AddRange(from c in list where c.ParentId == 0 select c);
19             //执行递归方法
20             AddNode(root, list);
21 
22             return root;
23         }
24 
25         //参数1:传入一个Category类型的节点,这里从root开始,
26         //参数2:第二个参数就是全部分类的集合,用于检索
27         public void AddNode(Category cate, List<Category> list)
28         {
29             for (int i = 0; i < cate.Children.Count; i++)
30             {
31                 //临时集合对象,存放parentId与父类的Id相等的对象
32                 List<Category> temp = (from c in list where c.ParentId == cate.Children[i].Id select c).ToList();
33                 //加入到Children属性中
34                 cate.Children[i].Children.AddRange(temp);
35                 //递归,执行方法本体
36                 AddNode(cate.Children[i], list);
37             }
38         }
39     }
40 }

Html页面的后台代码

 1 using Cong.Bll;
 2 using Cong.Model;
 3 using System;
 4 using System.Collections.Generic;
 5 using System.Linq;
 6 using System.Web;
 7 using System.Web.UI;
 8 using System.Web.UI.WebControls;
 9 
10 namespace WebApp
11 {
12     public partial class master : System.Web.UI.MasterPage
13     {
14         protected Category root { get; set; }
15 
16         protected void Page_Load(object sender, EventArgs e)
17         {
18             CategoryBll cb = new CategoryBll();
19 
20             root = cb.GetCategorys();
21         }
22     }
23 }

定义了root属性,把从Bll层查找到的数据存到root,便于前端代码输出。

前端Html代码:

 1 <div id="menu" class="dropdown hover-toggle">
 2                         <a class="navbar-brand dropdown-toggle" href="#">全部商品分类 <b class="caret"></b></a>
 3                         <!--data-toggle="dropdown"-->
 4                         <div class="clearfix"></div>
 5                         <ul id="categories" class="dropdown-menu">
 6                             <%foreach (var i in root.Children)
 7                                 {%>
 8                             <li>
 9                                 <a href="<%=i.Link %>.aspx"><i class="icon-main icon-<%=i %>"></i><%=i.Name %></a>
10                                 <ul class="sub-item">
11                                     <%foreach (var j in i.Children)
12                                         {%>
13                                     <li>
14                                         <a href="<%=j.Link %>.aspx"><%=j.Name %></a>
15                                         <ul class="sub-item">
16                                             <%foreach (var k in j.Children)
17                                                 {%>
18                                             <li><a href="<%=k.Link %>.aspx"><%=k.Name %></a></li>
19                                             <%} %>
20                                         </ul>
21                                     </li>
22                                     <% } %>
23                                 </ul>
24                             </li>
25 
26                             <%} %>
27                         </ul>
28                     </div>

这里使用的是前后台汇编的方法,在后台中已经获取了root节点,通过三层循环,把分类输出到前端。

界面是老师给的前端代码素材,我只是从SQL中查找数据,并且连接到前端。不过这里的前端用的是JQuery和BootStrap,有兴趣的话可以自己制作。

完成。之后还会更新其他部分的代码。

原文地址:https://www.cnblogs.com/chenyucong/p/5929249.html