前些天,教育訓練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,有興趣的話可以自己制作。
完成。之後還會更新其他部分的代碼。