无限级分类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 ...
随机推荐
- python之道02
猜数字,设定一个理想数字比如:66,让用户输入数字,如果比66大,则显示猜测的结果大了,然后继续让用户输入; 如果比66小,则显示猜测的结果小了,然后继续让用户输入;只有等于66,显示猜测结果正确,然 ...
- CentOS7.6 静态IP配置
1:选中安装好的虚拟机,点击“编辑”,然后选择“虚拟网络编辑器(N…)”,如下图所示: 2:选择桥接模式,在桥接到指定的本地网卡即可."确定"保存 3:选中虚拟机,右击虚拟机,选择 ...
- 【收藏】史上最全的浏览器 CSS & JS Hack 手册
浏览器渲染页面的方式各不相同,甚至同一浏览器的不同版本(“杰出代表”是 IE)也有差异.因此,浏览器兼容成为前端开发人员的必备技能.如果有一份浏览器 Hack 手册,那查询起来就方便多了.这篇文章就向 ...
- 2019西安多校联训 Day5
T1 光哥为了不让某初二奆佬恶心到我们而留下的火种 (貌似没这题平均分就100-了) 思路:就一横一竖让后就gztopa嘛 #include <bits/stdc++.h> using n ...
- c# xml本地化用法
1.普通格式 2.占位符格式 注意事项: 1.Pascal命名法 2.key只是key,中间不需要空格,value可以空格 3.占位符左右两边分别空一格
- Shell数值比较
Shell数值比较 比较 描述 n1 -eq n2 检查n1是否与n2相等 n1 -ge n2 检查n1是否大于或等于n2 n1 -gt n2 检查n1是否大于n2 n1 -le n2 检查n1是否小 ...
- 如何用纯 CSS 绘制一颗闪闪发光的璀璨钻石
效果预览 按下右侧的"点击预览"按钮在当前页面预览,点击链接全屏预览. 在线演示 https://codepen.io/zhang-ou/pen/qYqwQp 可交互视频教程 此视 ...
- shiro配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- FZU 1686 dlx重复覆盖
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> ...
- [luoguP1772] [ZJOI2006]物流运输(DP + spfa)
传送门 预处理cost[i][j]表示从第i天到第j天起点到终点的最短距离 f[i]表示前i天到从起点到终点的最短距离 f[0] = -K f[i] = min(f[i], f[j - 1] + co ...