无限级分类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. CSS中列表项list样式

    CSS列表属性 属性 描述 list-style-属性 用于把所有用于列表的属性设置于一个声明中. list-style-image 将图象设置为列表项标志. list-style-position ...

  2. Swift 中的Range和NSRange不同

    Swift中的Ranges和Objective-C中的NSRange有很大的不同,我发现在处理Swift中Ranges相关的问题的时候,总是要花费比我想象的更多的时间.不过,现在回过头来看看,发现Sw ...

  3. Visual C++中error spawning cl.exe错误的两种解决方法.

    可能很多人在安装VC 6.0后有过点击“Compile”或者“Build”后被出现的 “Compiling... ,Error spawning cl.exe”错误提示给郁闷过.很多人的 选择是重装, ...

  4. spoj-TSUM Triple Sums

    题目描述 题解: 很吊的容斥+$FFT$,但是并不难. 首先,由于有重复,我们要容斥. 怎么办? 记录三个多项式, 只取一个:$w1$; 相同物体拿两个:$w2$; 相同物体拿三个:$w3$; 然后答 ...

  5. js 异步编程方案

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise http://www. ...

  6. js实现复制粘贴功能

    在项目中使用到复制粘贴功能,虽然网上有很多大牛封装了很多的插件,但是还是想不去使用插件,就像自己来实现这个功能. 另一篇是禁止复制粘贴 前端er怎样操作剪切复制以及禁止复制+破解等 初步想法: 1. ...

  7. CSS--基础块级元素与内联元素

    在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素.在HTML和XHTML中,块级元素不能继承自行内元素(即不能嵌套在行内元素),<p&g ...

  8. MySQL 存储 utf8mb4

    1.如果是阿里云数据库 a.控制台->修改参数character_set_server参数为UTF8mb4 b.设置库的字符集为UTF8mb4 2.如果是自己mysql服务器 [client] ...

  9. SpringCloud源码地址

    SpringCloud实战源代码 https://github.com/springcloud/spring-cloud-code.git

  10. CSS小知识点一

    1.   text-indent属性    缩进文本 通过使用 text-indent 属性,所有元素的第一行都可以缩进一个给定的长度,甚至该长度可以是负值.这个属性最常见的用途是将段落的首行缩进,一 ...