前些天,培训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 Children { get; set; }
17
18 public Category()
19 {
20 this.Children = new List();
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();
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 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(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 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 list)
28 {
29 for (int i = 0; i < cate.Children.Count; i++)
30 {
31 //临时集合对象,存放parentId与父类的Id相等的对象
32 List 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
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,有兴趣的话可以自己制作。
完成。之后还会更新其他部分的代码。