无限级分类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. zabbix监控流程图

  2. scanf_s获取参数,清空缓冲区,判断是否读取成功

    #include<stdio.h> int main() { ]; ) { printf("Please input:\n"); ); ) { printf(" ...

  3. InnoDB 事务隔离级别

    InnoDB是一种平衡高可靠性和高性能的通用存储引擎.在MySQL数据库5.5.8版本开始,InnoDB是默认的MySQL存储引擎. InnoDB的主要优势 - 其DML操作遵循ACID,具有提交,回 ...

  4. python3.x Day6 IO多路复用

    IO多路复用import asyncio 这个是异步IO模块 这个还不知道怎么用 select poll epoll 都是IO多路复用 windows 仅支持select linux2.6以后 支持e ...

  5. pwnable.kr lotto之write up

    源代码 : #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcnt ...

  6. POJ 3680: Intervals【最小费用最大流】

    题目大意:你有N个开区间,每个区间有个重量wi,你要选择一些区间,使得满足:每个点被不超过K个区间覆盖的前提下,重量最大 思路:感觉是很好想的费用流,把每个区间首尾相连,费用为该区间的重量的相反数(由 ...

  7. winrar5.0破解

    RAR registration data Federal Agency for Education 1000000 PC usage license UID=b621cca9a84bc5deffbf ...

  8. 【BZOJ1225】求正整数(数论)

    题意:对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m. n<=50000 思路:记得以前好像看的是maigo的题解 n即为将m分解为质数幂次的乘积后的次数+1之积 经检验只需要 ...

  9. php之ThinkPHP的memcached类的修改

    php之ThinkPHP的memcached类的修改 在Think\Cache\Driver\Memcached.class.php中,增加方法获取错误信息的方法,方便调试, public funct ...

  10. python之-- 反射

    反射定义:通过字符串映射或者修改程序运行时的状态,属性,方法.方法有如下4个:1:getattr(object,name,default=None):根据字符串去获取obj对象里的对应的方法的内存地址 ...