无限级分类Asp.net Mvc实现
 
无限级分类涉及到异步加载子类、加载当前类和匹配问题,现在做一个通用的实现。
 
(一) 效果如下:
 
(二)设计、实现及使用
(1)数据库
(a)表设计dbo.Categories
列名
类型
说明
CategoryId
int
主键,增量为1的标识符
Name
nvarchar(50) 分类名称
ParentId
int
父类Id
Path
nvarchar(100)
分类路径,用以表示该类的层级关系
CreatedAt
datetime
创建时间

(b)测试数据


(2)前台设计
(a)分部视图-加载一个子类:_LoadCategory.cshtml
@using RspTest.Models;
@model int
@{
    Layout = null;
    var context = new MvcTestEntities();
    var subCats = new List<Category>();
    subCats = context.Categories.Where(x => x.ParentId == Model || Model == 0 && x.ParentId == null).ToList();
    var selectedCid = (int)ViewBag.selectedCid;
    }
@if(subCats.Count>0)
{
<select name="category" class="category">
    <option value="">请选择</option>
    @foreach (var sub in subCats)
    {
        <option value="@sub.CategoryId" @(sub.CategoryId == selectedCid?"selected":"")>@sub.Name</option>
    }
</select>
}
(b)分部视图-加类某个类:_LoadCategories.cshtml
@using RspTest.Models
@model int
@{
    Layout = null;
    var context = new MvcTestEntities();
    var currentCat = context.Categories.Find(Model);
    var cids = new List<int>{0};
    if(currentCat!=null)
    {
        if(!string.IsNullOrEmpty(currentCat.Path))
        {
            var paths = currentCat.Path.Split(',');
            int tmpCatId = 0;
            for(var i=0;i<paths.Length;i++)
            {
                var catIdStr = paths[i];
                if (int.TryParse(catIdStr, out tmpCatId))
                {
                    cids.Add(tmpCatId);
                }
            }
        }
    }
    cids.Add(0);//作为当前分类的子分类的默认选中值
    }
<div class="categories-wrap">
    @for (var i=0;i<cids.Count-1;i++)
    {
        var cid = cids[i];
        ViewBag.selectedCid = cids[i+1];
        @Html.Partial("_LoadCategory",cid)
    }
</div>
(c)视图-使用无限级分类进行查找:Index.cshtml
@using RspTest.Models
@model List<Category>
@{
    ViewBag.Title = "分类列表";
}
<h2>分类列表</h2>
<script src="~/Scripts/jquery-1.7.1.js"></script>
<style type="text/css">
    .category {
        margin-right:10px;
    }
    th,td {
        border:1px solid black;text-align:center;
    }
    tr {
        text-align:center;
    }
    fieldset {
        border:1px solid black;margin-top:10px;
    }
    form > ul > li {
        float:left;margin-right:15px;
        list-style-type:none;
    }
</style>
<fieldset>
    <legend>搜索</legend>
    <form action="/categories" method="get">
        <ul>
            <li>类别:</li>
            <li>
    @Html.Partial("_LoadCategories",(int)ViewBag.cid)
                </li>
            <li>
        <input type="submit" value="搜索" />
                </li>
            </ul>
    </form>
</fieldset>
<table>
    <thead>
        <tr>
            <th>编号</th>
            <th>名称</th>
            <th>父类</th>
            <th>路径</th>
        </tr>
    </thead>
    <tbody>
        @foreach(var cat in Model)
        {
            <tr>
                <td>
                    @cat.CategoryId
                </td>
                <td>
                    @cat.Name
                </td>
                <td>
                    @cat.ParentId
                </td>
                <td>
                    @cat.Path
                </td>
            </tr>
        }
    </tbody>
</table>
<script type="text/javascript">
    $(document).ready(function () {
        $(".category").live("change", function (e) {
            var $current = $(this);
            if ($current.val() == "") {
                $current.nextAll(".category").remove();
                return false;
            }
            $.ajax({
                url: "/categories/getsubcategories/" + $current.val(),
                type: "post",
                success: function (data, text) {
                    //alert(data);
                    //先清除所以子分类
                    $current.nextAll(".category").remove();
                    var $eles = $(data);
                    if ($eles.find("option").length > 1) {//除去“请选择”之外,还有选项的情况才加载子类
                        $eles.insertAfter($current);
                    }
                    else {
                    }
                }
            })
        });
    });
</script>
 
(3)后台代码
(a)Action-异步获取子类:GetSubCategories
public ActionResult GetSubCategories(int id)
        {
            ViewBag.selectedCid = 0;
            return View("_LoadCategory", id);
        }
(b)Action-分类列表:Index
public ActionResult Index()
        {
            int cid = 0;
            if (!string.IsNullOrEmpty(Request.Params["category"]))
            {
                //一般会按name将元素的值用“,”连接起来,因此,需要取该参数的最后一个合法值
                var cidsStr = Request.Params["category"].Trim();
                foreach (var cidStr in cidsStr.Split(','))
                {
                    var tmpCid = 0;
                    if (int.TryParse(cidStr, out tmpCid))
                    {
                        cid = tmpCid;
                    }
                }
            }
            var category = context.Categories.Find(cid);
            var pathSearch = ","+cid+",";
            ViewBag.cid = cid;
            var categories = context.Categories.Where(x => x.Path.Contains(pathSearch) || cid == 0).ToList();
            return View(categories);
        }
 
说明:一个页面,可加载多个分类。
 
文章系本人原创,欢迎转载,转载时请注明出处。

无限级分类Asp.net Mvc实现的更多相关文章

  1. ASP.NET MVC使用Bootstrap系列(4)——使用JavaScript插件

    阅读目录 序言 Data属性 VS 编程API 下拉菜单(dropdown.js) 模态框(modal.js) 标签页(tab.js) 工具提示(tooltip.js) 弹出框(popover.js) ...

  2. ASP.NET MVC使用Bootstrap系列(1)——开始使用Bootstrap

    阅读目录 Bootstrap结构介绍 在ASP.NET MVC 项目中添加Bootstrap文件 为网站创建Layout布局页 使用捆绑打包和压缩来提升网站性能 在Bootstrap项目中使用捆绑打包 ...

  3. ASP.NET MVC学习系列(二)-WebAPI请求(转)

    转自:http://www.cnblogs.com/babycool/p/3922738.html 继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的g ...

  4. (转)ASP.NET MVC 学习第一天

    天道酬勤0322   博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅  | 管理 随笔:10 文章:0 评论:9 引用:0 ASP.NET MVC 学习第一天 今天开始第一天学习as ...

  5. Cordova+Asp.net Mvc+GIS

    Cordova+Asp.net Mvc+GIS跨平台移动应用开发实战1-系统初步搭建(附演示,apk,全部源码)   1.前言 身处在移动互联网的今天,移动应用开发炙手可热,身为程序猿的我们怎么能错过 ...

  6. Asp.net MVC + EF + Spring.Net 项目实践3

    Asp.net MVC + EF + Spring.Net 项目实践 这一篇要整合Model层和Repository层,提供一个统一的操作entity的接口层,代码下载地址(博客园上传不了10M以上的 ...

  7. ASP.NET MVC局部视图

    使用ASP.NET MVC局部视图避免JS拼接HTML,编写易于维护的HTML页面   以前使用ASP.NET WebForm开发时,喜欢使用Repeater控件嵌套的方式开发前台页面,这样就不用JS ...

  8. ASP.NET MVC进阶

    ASP.NET MVC进阶 一.ASP.NET MVC中的AJAX应用 首先,在ASP.NET MVC中使用自带的ajax功能,必须要导入2个js文件(顺序不能颠倒): ASP.NET MVC提供了2 ...

  9. ASP.NET MVC Model绑定

    ASP.NET MVC Model绑定(一) 前言 ModelMetadata系列的结束了,从本篇开始就进入Model绑定部分了,这个系列阅读过后你会对Model绑定有个比较清楚的了解, 本篇对于Mo ...

随机推荐

  1. lspci详解分析

    lspci详解分析 一.PCI简介 PCI是一种外设总线规范.我们先来看一下什么是总线:总线是一种传输信号的路径或信道.典型情况是,总线是连接于一个或多个导体的电气连线,总 线上连接的所有设备可在同一 ...

  2. ubuntu18.04server 真机无法自动获取IP解决方法

    输入命令ip a,查看自己网卡编号,比如我的就是ens33 因为此图为虚拟机搭建的,所以网卡名称为ens33,如果是真机的话则是enp0s**的名字 2.修改netwlpan文件 1 sudo vim ...

  3. 纯html+css中实现静态选座位效果技巧(input+label使用小技巧)

    很多时候,我们想通过html+css的方式实现排列在后方的代码在选中状态下,能控制排列在前的代码的样式.那么要怎么实现呢?在这里我就要用1个小技巧来完成. 众所周知的,我们css中的选择器通常只能向下 ...

  4. HNOI2006 花仙子的魔法

    题目描述 题解: 考试的时候手画打表,然后半个小时磨了个式子:$$f[i][j]=f[i-1][j-1]+f[i][j-1]$$ 交上去$A$的时候都蒙了. 考后才知道原因. 考虑$n$维空间内原来有 ...

  5. (10) openssl dhparam(密钥交换)

    openssl dhparam用于生成和管理dh文件.dh(Diffie-Hellman)是著名的密钥交换协议,或称为密钥协商协议,它可以保证通信双方安全地交换密钥. 但注意,它不是加密算法,所以不提 ...

  6. jquery validate基本

    http://www.runoob.com/jquery/jquery-plugin-validate.html jquery validate 默认 在键盘按下并释放及提交后验证提交表单 例如: $ ...

  7. 算法导论 第九章 中位数和顺序统计量(python)

    第i个顺序统计量:该集合中第i小的元素(建集合排序后第i位 当然算法可以不排序) 中位数:集合中的中点元素 下中位数 上中位数 9.1最大值和最小值 单独的max或min每个都要扫一遍 n-1次比较 ...

  8. luogu3302 [SDOI2013]森林

    前置技能:Count on a tree 然后带上一个启发式合并 #include <algorithm> #include <iostream> #include <c ...

  9. MySql查询语句的使用实例

    一.设计表 1.设计表 查询语句之前先设计四张表:student.teacher.course.score student:sid(学号).sname(姓名).sage(年龄).ssex(性别) te ...

  10. IBM MQ 创建以及常见问题集锦

    消息队列+发送队列+消息通道 接收通道名称与发送端的发送通道名称要一致,修改通道信息后要执行 start channle(chlname) 重启通道.常用的MQ命令 66.0.42.240 用户 mq ...