无限级分类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. PHP23 AJAX分页

    模型代码设计 以留言信息管理为例. 获取根据条件查询记录总数和分页数据. <?php namespace application\admin\models; use core\mybase\Mo ...

  2. packet capture

    1.下载地址:https://www.coolapk.com/apk/app.greyshirts.sslcapture

  3. Fiddler设置显式IP地址

    打开Fiddler, 菜单栏:Rules->Customize Rules… 或快捷键 Ctrl+R . 通过快捷键 Ctrl+F ,搜索:static function Main() 函数. ...

  4. HLS协议分析实现与相关开源代码

        苹果定义的HLS协议,广泛运用在现在很多的流媒体服务器和客户端之间,用以传输直播电视数据流.    具体的协议参照    http://tools.ietf.org/html/draft-pa ...

  5. jquery-closest

    1.closest() 本例演示如何通过 closest() 完成事件委托.当被最接近的列表元素或其子后代元素被点击时,会切换黄色背景: $( document ).bind("click& ...

  6. ICPC-Beijing 2006 狼抓兔子

    题目描述 题解: 裸的最小割. 但是最大流跑不过去怎么办? 转变一下,既然最大流是一条左下<->右上的通路,我们可以把图划分为若干区域, 最后找左下到右上的最短路就行了. 代码: #inc ...

  7. CentOS7安装Tomcat9并配置

    划重点:安装tomcat之前必须先安装jdk  安装教程 1.下载 Tomcat 9 CentOS 7 下创建目录并下载文件:// 链接已更新 cd /usr/local/ mkdir tomcat ...

  8. 【终极指南】图文详解Chrome插件离线安装方法

    Chrome插件离线安装背景介绍 因为无法访问Google所以国内用户目前大多只能通过第三方比如我们Chrome插件网下载插件,然后离线安装.Chrome官方自67版本后,只允许用户通过谷歌应用商店安 ...

  9. shiro配置文件

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  10. 杭电 2141 Can you find it? (二分法)

    Description Give you three sequences of numbers A, B, C, then we give you a number X. Now you need t ...