无限级分类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使用Bootstrap系列(4)——使用JavaScript插件
阅读目录 序言 Data属性 VS 编程API 下拉菜单(dropdown.js) 模态框(modal.js) 标签页(tab.js) 工具提示(tooltip.js) 弹出框(popover.js) ...
- ASP.NET MVC使用Bootstrap系列(1)——开始使用Bootstrap
阅读目录 Bootstrap结构介绍 在ASP.NET MVC 项目中添加Bootstrap文件 为网站创建Layout布局页 使用捆绑打包和压缩来提升网站性能 在Bootstrap项目中使用捆绑打包 ...
- ASP.NET MVC学习系列(二)-WebAPI请求(转)
转自:http://www.cnblogs.com/babycool/p/3922738.html 继续接着上文 ASP.NET MVC学习系列(一)-WebAPI初探 来看看对于一般前台页面发起的g ...
- (转)ASP.NET MVC 学习第一天
天道酬勤0322 博客园 | 首页 | 发新随笔 | 发新文章 | 联系 | 订阅 | 管理 随笔:10 文章:0 评论:9 引用:0 ASP.NET MVC 学习第一天 今天开始第一天学习as ...
- Cordova+Asp.net Mvc+GIS
Cordova+Asp.net Mvc+GIS跨平台移动应用开发实战1-系统初步搭建(附演示,apk,全部源码) 1.前言 身处在移动互联网的今天,移动应用开发炙手可热,身为程序猿的我们怎么能错过 ...
- Asp.net MVC + EF + Spring.Net 项目实践3
Asp.net MVC + EF + Spring.Net 项目实践 这一篇要整合Model层和Repository层,提供一个统一的操作entity的接口层,代码下载地址(博客园上传不了10M以上的 ...
- ASP.NET MVC局部视图
使用ASP.NET MVC局部视图避免JS拼接HTML,编写易于维护的HTML页面 以前使用ASP.NET WebForm开发时,喜欢使用Repeater控件嵌套的方式开发前台页面,这样就不用JS ...
- ASP.NET MVC进阶
ASP.NET MVC进阶 一.ASP.NET MVC中的AJAX应用 首先,在ASP.NET MVC中使用自带的ajax功能,必须要导入2个js文件(顺序不能颠倒): ASP.NET MVC提供了2 ...
- ASP.NET MVC Model绑定
ASP.NET MVC Model绑定(一) 前言 ModelMetadata系列的结束了,从本篇开始就进入Model绑定部分了,这个系列阅读过后你会对Model绑定有个比较清楚的了解, 本篇对于Mo ...
随机推荐
- CSS中列表项list样式
CSS列表属性 属性 描述 list-style-属性 用于把所有用于列表的属性设置于一个声明中. list-style-image 将图象设置为列表项标志. list-style-position ...
- Swift 中的Range和NSRange不同
Swift中的Ranges和Objective-C中的NSRange有很大的不同,我发现在处理Swift中Ranges相关的问题的时候,总是要花费比我想象的更多的时间.不过,现在回过头来看看,发现Sw ...
- Visual C++中error spawning cl.exe错误的两种解决方法.
可能很多人在安装VC 6.0后有过点击“Compile”或者“Build”后被出现的 “Compiling... ,Error spawning cl.exe”错误提示给郁闷过.很多人的 选择是重装, ...
- spoj-TSUM Triple Sums
题目描述 题解: 很吊的容斥+$FFT$,但是并不难. 首先,由于有重复,我们要容斥. 怎么办? 记录三个多项式, 只取一个:$w1$; 相同物体拿两个:$w2$; 相同物体拿三个:$w3$; 然后答 ...
- js 异步编程方案
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise http://www. ...
- js实现复制粘贴功能
在项目中使用到复制粘贴功能,虽然网上有很多大牛封装了很多的插件,但是还是想不去使用插件,就像自己来实现这个功能. 另一篇是禁止复制粘贴 前端er怎样操作剪切复制以及禁止复制+破解等 初步想法: 1. ...
- CSS--基础块级元素与内联元素
在CSS中,html中的标签元素大体被分为三种不同的类型:块状元素.内联元素(又叫行内元素)和内联块状元素.在HTML和XHTML中,块级元素不能继承自行内元素(即不能嵌套在行内元素),<p&g ...
- MySQL 存储 utf8mb4
1.如果是阿里云数据库 a.控制台->修改参数character_set_server参数为UTF8mb4 b.设置库的字符集为UTF8mb4 2.如果是自己mysql服务器 [client] ...
- SpringCloud源码地址
SpringCloud实战源代码 https://github.com/springcloud/spring-cloud-code.git
- CSS小知识点一
1. text-indent属性 缩进文本 通过使用 text-indent 属性,所有元素的第一行都可以缩进一个给定的长度,甚至该长度可以是负值.这个属性最常见的用途是将段落的首行缩进,一 ...