• 无限级分类Asp.net Mvc实现


    无限级分类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);
            }
     
    说明:一个页面,可加载多个分类。
     
    文章系本人原创,欢迎转载,转载时请注明出处。
  • 相关阅读:
    解决使用gomod后goland导包报红问题
    Golang写文件的坑
    Golang去除字符串前后空格
    Golang通过结构体解析和封装XML
    Golang获取CPU、内存、硬盘使用率
    Golang数组和切片的区别
    Golang修改操作系统时间
    Golang中GBK和UTF8编码格式互转
    Golang中的各种时间操作
    Golang十六进制字符串和byte数组互转
  • 原文地址:https://www.cnblogs.com/xiaxiazl/p/3440169.html
Copyright © 2020-2023  润新知