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