天天看點

使用遞歸制作仿京東淘寶的商品分類導航欄

前些天,教育訓練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,有興趣的話可以自己制作。

完成。之後還會更新其他部分的代碼。