无限分类的ASP实现方法

做网站的,应该经常遇到使用分类功能的,通常有个二级三级分类已经很不错,在实现上,这些也不是很难的。但是对于某些系统,却需要实现更多级分类,例如文章系统,分类级数是不确定的,所以现在网上的系统中基本都采用无限分类。

看到很多地方都有关于无限分类实现的教程,也有人说这个是非常简单的功能。简单与否,在于每个人的能力了。

现在我们也来考察一下如何实现这个无限分类。在这里我采用的是 ASP(VBScript) 结合 Access 数据库来实现。

通常对于分类,我们需要有类别的编号和类别的名称,所以我们在数据库中定义这两个字段,ID 和 Title,ID 字段为自动编号,Title 选择文本类型。

但 是如果仅有这两个字段,能实现的恐怕只有一级分类了。多级分类中,不同级之间都会存在关联性,即每个子类别,都应该是唯一地属于某个父类别的,所以在数据 库中,我们表现出当前子类别所属的父类别即可。鉴于此,我们增加一个字段ParentID,保存父类别 ID 值。对于根类别,我们可以设置这个值为 0 。

至此,基本上就可以具备了无限级分类所必需的数据。

但是在实际使用中,出于效率问题,我们增加进两个字段:

IDPath - 用来保存当前类别的 ID 路径,即从顶层到当前类别的各级分类的 ID ,各级层间用分隔符“|”分隔。
TitlePath - 用来保存当前类别的 Title 路径,即每级分类的标题,各级层间用分隔符“|”分隔。

鉴于是要实现无限分类,上面两个字段的内容可能会很长,所以我们选择备注类型。具体的作用,在后面的程序中可以明了。

这样我们得到完整的数据库:

ID - 分类编号 - 自动编号
Title - 分类标题 - 文本
ParentID - 父类别编号 - 整数
IDPath - 分类层次编号路径 - 备注
TitlePath - 分类层次标题路径 - 备注

我们首先来考察如何显示表中已经存在的数据。先给出代码:

代码:
Sub listData
    Dim intSortID : intSortID = CID(Request.QueryString("SortID"))

Dim rs, sql
Set rs = Server.CreateObject("ADODB.Recordset")
sql = "Select s.ID, s.Title, s.IDPath, s.TitlePath, (Select Count(*) FROM Sorts ss Where ss.ParentID = s.ID) AS iCount FROM Sorts s Where s.ParentID = " & intSortID & ";"
rs.Open sql, conn, 1, 1, 1
If rs.RecordCount > 0 Then
    Dim arrIDs, arrTitles, intLoop

    Response.Write("<table width=""100%"" cellpadding=""3"" cellspacing=""1"" border=""0"" bgcolor=""#CCCCCC"">")
Response.Write("<tr bgcolor=""#E0E0E0""><th>分类名</th><th>子类别数目< /th><th>分类层级</th></tr>")

Do While Not rs.EOF
    Response.Write("<tr bgcolor=""#FFFFFF""><td><a href=""?action=list&SortID=" & rs("ID") & """>" & rs("Title") & "</a>&nbsp;<img src="/blog/"images/icon_new_window.gif"" width=""11"" height=""14"" border=""0"" alt=""打开功能菜单"" title=""打开功能菜单"" οnclick=""showMenu(event, ’’, ’" & rs("ID") & "’);"" /></td><td>" & rs("iCount") & "</td><td><a href=""?action=list&SortID=0"">根</a>&nbsp;&raquo; &nbsp;")

’    数据入库的时候保证 IDPath 和 TitlePath 不为空
arrIDs = Split(rs("IDPath"), "|")
arrTitles = Split(rs("TitlePath"), "|")

For intLoop = 0 To UBound(arrIDs)
    If intLoop = UBound(arrIDs) Then    ’    如果是最后一级
    Response.Write("<a href=""?action=list&SortID=" & arrIDs(intLoop) & """>" & arrTitles(intLoop) & "</a>")
Else
    Response.Write("<a href=""?action=list&SortID=" & arrIDs(intLoop) & """>" & arrTitles(intLoop) & "</a>&nbsp;&raquo;&nbsp;")
End If
Next

Response.Write("</td></tr>")

rs.MoveNext
Loop

Response.Write("</table>")
Else
    Response.Write("暂无子类别,是否<a href=""?action=add&SortID=" & intSortID & """>添加</a>?")
End If
rs.Close
Set rs = Nothing
End Sub
我们将列出分类的代码写入一段子程序 listData,其中变量 intSortID 是传递过来的一个类别编号,而我们要显示的是该类别下的子类别。

对于第一级分类,这个编号为 0。

CID() 函数是自定义的函数,用于将字符串转换为 ID 类型的数据,即大于等于 0 的整数,后面还会多次用到这个自定义函数,代码如下:
代码:
’--------------------------------------------------------------------------------
Function CID(strS)
’--------------------------------------------------------------------------------
’    转换为有效的 ID
’    返回值类型:Integer (>=0)
’--------------------------------------------------------------------------------
    Dim intI
intI = 0

    If IsNull(strS) or strS = "" Then
    intI = 0
Else
    If Not IsNumeric(strS) Then
    intI = 0
Else
    Dim intk
    On Error Resume Next
intk = Abs(Clng(strS))
If Err.Number = 6 Then intk = 0  ’’数据溢出
Err.Clear
    intI = intk
End If
End If

CID = intI
End Function
数据库操作,就是从表中找到 ParentID = intSortID 的记录,然后循环显示。

在针对 IDPath 和 TitlePath 这两个字段的内容上,定义两个数组 arrIDs 和 arrTitles ,分别循环显示类别层次即可。这里需要注意最后一个层次(在我的代码中,最后一级即为当前分类),其后是不包括箭头标示的,表示已经是当前分类了。

当没有记录的时候,显示提示信息,并有一个增加分类的链接。

因为所有的添加、编辑、删除、列表操作我放在一个页面中,所以链接中有个 action 变量来确定是进行哪步操作。

另外,显示的分类标题后面有个小图标,点击能显示功能菜单,相应的代码在后面给出。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值