今天在项目中有这么一个需求:“用户可以选择自己关注的文章分类,文章分类又分两级”。
在网上参考了 w809026418 的“ASP.NET MVC 3 CheckBoxList 的使用”,里面原理讲的很清楚,这里不再说了。但并不能完全满足我的需求,所以在他基础上进行了修改和扩展。
1、首先在Controller中的Index,获取用户已经选择的文章分类和全部文章分类进行对应。
class="brush:csharp;gutter:true;">public ActionResult Index()
{
var userId = new Guid("f7fc34332c2242b2b357307980d26fa7");
// 获取用户已经选择的文章分类
var focusCategories = focusCategoryService.GetFocusedCategoriesByUser(userId);
// 获取全部文章分类
var documentCategories = documentCategoryService.GetAll();
// 构建文章层级
ViewBag.DocumentCategories = new DocumentCategorySelectListItem().GetDocumentCategory(documentCategories, focusCategories);
return View();
}
2、扩展SelectListItem,将文章分类子节点做成二级项,里面还包括一个方法将用户已选择的文章分类属性 Selected = true
public class DocumentCategorySelectListItem : SelectListItem
{
/// <summary>
/// 子节点
/// </summary>
public IEnumerable<SelectListItem> ChildItems { get; set; }
/// <summary>
/// 构建文章层级,并将用户已选择的文章分类Selected=true
/// </summary>
/// <param name="documentCategories">所有文档分类</param>
/// <param name="focusCategories">关注文档分类</param>
/// <returns>返回前台需要CheckList</returns>
public IEnumerable<DocumentCategorySelectListItem> GetDocumentCategory(IEnumerable<DocumentCategoryDTO> documentCategories, IEnumerable<DocumentCategoryDTO> focusCategories)
{
var result = new List<DocumentCategorySelectListItem>();
if (documentCategories.Any())
{
// 查找父节点
foreach (var category in documentCategories.Where(d => d.PraentId == Guid.Empty))
{
var documentCategorySelectListItem = new DocumentCategorySelectListItem
{
Text = category.Name,
Value = category.Id.ToString(),
// 在关注分类中查找是否存在
Selected = focusCategories.Where(f => f.Id == category.Id).Count() > 0
};
var childItems = new List<SelectListItem>();
// 查找子节点
var childDocumentCategories = documentCategories.Where(d => d.PraentId != Guid.Empty && d.PraentId == category.Id);
foreach (var childDocumentCategory in childDocumentCategories)
{
var categoryItem = new SelectListItem
{
Text = childDocumentCategory.Name,
Value = childDocumentCategory.Id.ToString(),
Selected = focusCategories.Where(f => f.Id == childDocumentCategory.Id).Count() > 0
};
childItems.Add(categoryItem);
}
documentCategorySelectListItem.ChildItems = childItems;
result.Add(documentCategorySelectListItem);
}
}
return result;
}
}
3、在Index.cshtml做显示
<h4>文章分类:</h4>
<div>
@Html.CheckBoxList("DocumentCategory", (IEnumerable<DocumentCategorySelectListItem>)ViewBag.DocumentCategories)
</div>
<div class="pull-right">
<input type="button" id="SubmitDocumentCategory" class="click" value="提交" />
</div>
4、Index.cshtml 页面使用 jQuery ajax 提交数据
$('#SubmitDocumentCategory').click(function () {
var arrs = new Array();
var chenked = $("input[type='checkbox']:checked").val([]);
for (var i = 0; i < chenked.length; i++) {
arrs[i] = chenked[i].value;
}
$.ajax({
url: "/FileLibrary/ModifyFocusedCategories",
type: 'post',
data: { "categories": arrs },
dataType: "json",
traditional:true,
success: function (data) {
alert(data.responseText);
},
error: function (data) {
alert(data.responseText);
}
});
return false;
});
5、提交给controller中的修改文章分类方法
/// <summary>
/// Ajax提交用户关注分类
/// </summary>
/// <param name="categories"></param>
/// <returns></returns>
[HttpPost]
public ActionResult ModifyFocusedCategories(List<string> categories)
{
if (Request.IsAjaxRequest())
{
if (categories !=null && categories.Count > 0)
{
var userId = new Guid("f7fc34332c2242b2b357307980d26fa7");
// 修改关注分类(自己的业务方法)
focusCategoryService.ModifyFocusedCategories(userId, categories);
return Content("用户关注修改成功!");
}
}
return View();
}
完成!!效果如图:

生成的HTML代码:
<div class="checkboxlist">
<ul>
<li>
<input type="checkbox" name="DocumentCategory" value="4af29fad-4f43-48b9-a3df-fe01c2960d36" />社会经济发展规划
<ul>
<li>
<input type="checkbox" name="DocumentCategory" value="4af29fad-4f43-48b9-a3df-fe01c2960d37" />国民经济和社会发展五年规划</li>
<li>
<input type="checkbox" name="DocumentCategory" value="cc43de4f-ef10-cf7a-1788-08d0bfa55bf0" />统计公报</li>
</ul>
</li>
<li>
<input type="checkbox" name="DocumentCategory" value="4ac54dfc-511a-c318-1788-08d0bfa55bf0" checked="chekced" />行业发展规划
<ul>
<li>
<input type="checkbox" name="DocumentCategory" value="fc0b0417-e590-c2f2-1788-08d0bfa55bf0" checked="chekced" />重点行业发展规划</li>
</ul>
</li>
</ul>
</div>
最后遗留3个问题:
1、为什么提交后局部页面刷新了?之前选择的都没了;
2、没有做到父子节点的联动选择;
3、为什么返回的提示信息,在Error方法中弹出?