首先请查一下最终的效果:
实现的思路很简单,即首构建一个JSON数据,这里已经通过后台排好序并且已做好了父子关系,然后通过QUI列表控件显示出来,也可以直接用HTML显示,代码如下:
<!--框架必需start-->
<script type="text/javascript" charset="utf-8" src="@Url.Content("~/libs/js/language/cn.js")"></script>
<script type="text/javascript" charset="utf-8" src="@Url.Content("~/libs/js/framework.js")"></script>
<link href="@Url.Content("~/libs/css/import_basic.css")" rel="stylesheet" type="text/css" />
<link rel="stylesheet" type="text/css" id="skin" />
<!--框架必需end-->
<!--数据表格start-->
<script type="text/javascript" charset="utf-8" src="@Url.Content("~/libs/js/table/quiGrid.js")"></script>
<!--数据表格end-->
<script type="text/javascript" src="@Url.Content("~/libs/js/popup/dialog.js")"></script>
<link href="@Url.Content("~/libs/skins/blue/style.css")" rel="stylesheet" type="text/css" id="theme" themecolor="green" positiontarget="positionContent" />
<div class="main">
<ul class="mainMenu" id="mainMenu">
<li class="func"><i></i><a href="@Url.Action("Index", "Fun")">功能库</a></li>
<li class="app"><i></i><a href="@Url.Action("Index", "App")">应用库</a></li>
<li class="active set"><i></i><a href="@Url.Action("Index", "Cls")">应用分类维护</a></li>
</ul>
<div class="content">
<!-- end leftTree -->
<div class="rightCon" style="width: 980px;">
<div class="rightCon-tit">
<h1>应用分类维护</h1>
</div>
<div class="maintain">
<div class="search">
<div>
@* <label for="" class="ml20">菜单名称:</label><input type="text" class="input mr20" style="width: 200px;height: 35px;">
<input type="button" class="btn" value="查 询">
<input type="button" class="btn" value="重 置">*@
<input type="button" class="btn add" value="添加一级分类" style="margin-left: 20px;" οnclick="onAdd(0, -1);">
</div>
<div class="buttons">
</div>
</div>
<div class="m-container">
<div id="maingrid"></div>
</div>
</div>
<!-- end maintain -->
</div>
<!-- end rightCon -->
</div>
<!-- end content -->
</div>
<script type="text/javascript">
var g;
function initComplete() {
g = $("#maingrid").quiGrid({
columns: [
{ display: '分类名称', name: 'ClsName', id: 'ClsId', width: 400, align: 'left' },
{ display: '创建时间', name: 'CreateTime', width: 250, align: 'center' },
{
display: '操作', isAllowHide: false, align: 'center', width: "250",
render: function (rowdata, rowindex, value, column) {
var str = '<div class="padding_left5"><span class="icon_add hand" title="新增子级" οnclick=onAdd("' + rowdata.ClsId + '","' + rowdata.ClsDepth + '","' + rowindex + '")>新增子级</span> ';
if (rowdata.id != -1 && rowdata.id != 0) {
str += '<span class="icon_edit hand" title="修改" οnclick=onEdit("' + rowdata.ClsId + '","' + rowdata.ClsName + '","' + rowindex + '")>修改</span> '
str += '<span class="icon_delete hand" title="删除" οnclick=onDelete("' + rowdata.ClsId + '","' + rowindex + '")>删除</span> '
}
str += '</div>';
return str;
}
}
],
data: {@Html.Raw(ViewBag.TreeData) },
height: '450', width: "100%", headerRowHeight: '40', rowHeight: '33', checkbox: false, usePager: false, autoCheckChildren: false, tree: { columnId: 'ClsId' }
});
}
var rowindexs;
/*新增*/
function onAdd(id, depth, rowindex) {
if (depth > 2) {
alert('最多只能添加三级分类');
return;
}
rowindexs = rowindex;
top.Dialog.open({
URL: "@Url.Action("Info", "Cls")" + "?clsId=" + id + "&type=add&userid=@ViewBag.UserId&clsName=",
Title: "新增分类",
Width: 450,
Height: 200
});
}
/*修改*/
function onEdit(id, clsName, rowindex) {
rowindexs = rowindex;
top.Dialog.open({
URL: "@Url.Action("Info", "Cls")" + "?clsId=" + id + "&type=edit&userid=@ViewBag.UserId&clsName=" + clsName,
Title: "修改分类",
Width: 450,
Height: 200
});
}
/*删除*/
function onDelete(id, rowindex) {
if (confirm("您确定要删除选中的分类吗?")) {
$.post("@Url.Action("Del", "Cls")", { clsId: id }, function (data) {
if (data.toString() == "-1") {
alert("该分类已被关联或使用,无法执行删除操作!");
} else if (data.toString() == "-2") {
alert("该分类下还有子级分类,请先删除!");
} else if (data.toString() == "1") {
alert("操作成功!");
deleteGridRow(rowindex);
} else {
alert("操作失败,请与管理员联系!");
}
}, "text");
}
}
function deleteGridRow(rowindexs) {
var row = g.getRow(rowindexs);
var parent = g.getParent(row);
var sister = g.getChildren(g.getParent(row));
g.deleteRow(row);
if (sister.length == 1) {
parent.isParent = false;
parent._hasChildren = false;
parent.iconClass = "icon_star";
parent.open = false;
}
g.reRender(g.records);
}
function addOrUpdateRow(type, clsId, clsName, parentId, createTime) {
var row = g.getRow(rowindexs);
var childs = g.getChildren(row);
var sister = g.getChildren(g.getParent(row));
if (type == "add") { //新增并且展开 或者 新增下面无子节点
//设置父级的相关属性
row.isParent = true;
row._hasChildren = true;
row.open = true;
row.iconClass = "icon_star";
//获取位置
var child = null;
var isdown = false;
//根据参数获得一个rowdate
var rowData = {
ClsId: clsId,
ClsName: clsName,
CreateTime: createTime,
ClsParentId: parentId,
iconClass: "icon_star"
}
//将rowdate新增进g
g.appendRow(rowData, row, child, true);
//如果是最大数字
g.expand(row);
} else if (type == "edit") { //修改
ClsId = clsId,
ClsName = clsName,
CreateTime = createTime,
ClsParentId = parentId,
g.reRender(g.records);
}
//重新渲染
}
function refershList() {
}
</script>
后台构建树型菜单JSON数据代码如下:
public ActionResult Index()
{
ViewBag.TreeData = GetAppClsList();
ViewBag.UserId = "";
return View();
}
public String GetAppClsList()
{
List<D_AppCls> List = _clsBll.GetAppClsList();
string data = JsonHelper.ConvertToJson(List).Replace("\"", "\"");
string json = String.Format("\"{0}\":{1}", "rows", data);
return json;
}
/// <summary>
/// 转换JSON对象集合,包含子集,递归加载
/// </summary>
/// <param name="companyList"></param>
/// <returns></returns>
public static string ConvertToJson(List<D_AppCls> companyList)
{
string json = "[";
//获取第一级目录
List<D_AppCls> rootList = companyList.Where(x => x.ClsParentId==0).ToList<D_AppCls>();
foreach (D_AppCls root in rootList)
{
string js = ConvertToJson(root);
string children = "";
children = DiGui(companyList, children, root.ClsId);
json += "{" + string.Format(js, children) + "},";
}
if (json.LastIndexOf(",") < 1)
{
json += "]";
}
else
{
json = json.Substring(0, json.Length - 1) + "]";
}
return json.Replace(",children:[]", null);
}
/// <summary>
/// 递归调用添加包含子集的JSON数组
/// </summary>
private static string DiGui(List<D_AppCls> companyList, string children, int pid)
{
children = "[";
List<D_AppCls> childerList = companyList.Where(x => x.ClsParentId == pid).ToList<D_AppCls>();
foreach (D_AppCls item in childerList)
{
string js = ConvertToJson(item);
string cd = "";
cd = DiGui(companyList, cd, item.ClsId);
children += "{" + string.Format(js, cd) + "},";
}
if (children.LastIndexOf(",") < 1)
{
children += "]";
}
else
{
children = children.Substring(0, children.Length - 1) + "]";
}
return children;
}
当然还有其它各种实现方法,如直接指定父子项的字段,交给前端UI来处理层级关系(ztree控件),但这种方式更为灵活,可以指定多列数据属性的显示,还可以控制菜单项的状态等,留给我们更多的开发和定制余地。