您的位置:首页 > 编程语言 > ASP

asp.net mvc + ExtJs 实现无限级TreePanel 加载、添加、编辑、删除

2011-05-16 16:53 841 查看
  以前用过Ext.tree.TreePanel 做过树形结构的查询绑定,感觉TreePanel还蛮好。

今天来尝试下 结合Ext.menu.Menu 菜单做一个增删改的功能,并实现无限级的绑定,如下图的效果:



第一步:TreePanel的无限级加载设计:

我的数据设计结构如下图:



第二步:后台获取级联数据结构,返回json数据类型:

[{"id":7,"text":"2011","leaf":false,"expanded":true,"children":[{"id":8,"text":"春季","leaf":false,"expanded":true,"children":[{"id":21,"text":"五月","leaf":false,"expanded":true,"children":[{"id":26,"text":"第四周","leaf":false,"expanded":true,"children":[{"id":28,"text":"星期五","leaf":true,"expanded":false,"children":[]},{"id":27,"text":"星期四","leaf":true,"expanded":false,"children":[]},{"id":23,"text":"星期三","leaf":true,"expanded":false,"children":[]},{"id":16,"text":"星期二","leaf":true,"expanded":false,"children":[]},{"id":12,"text":"星期一","leaf":true,"expanded":false,"children":[]}]},{"id":25,"text":"第三周","leaf":true,"expanded":false,"children":[]},{"id":24,"text":"第二周","leaf":true,"expanded":false,"children":[]},{"id":17,"text":"第一周","leaf":true,"expanded":false,"children":[]}]},{"id":20,"text":"四月","leaf":true,"expanded":false,"children":[]},{"id":19,"text":"三月","leaf":true,"expanded":false,"children":[]}]}]},{"id":4,"text":"2010","leaf":false,"expanded":true,"children":[{"id":13,"text":"秋季","leaf":false,"expanded":true,"children":[{"id":10,"text":"九月","leaf":false,"expanded":true,"children":[{"id":11,"text":"第一周","leaf":true,"expanded":false,"children":[]}]}]},{"id":6,"text":"夏季","leaf":false,"expanded":true,"children":[{"id":22,"text":"六月","leaf":true,"expanded":false,"children":[]}]},{"id":5,"text":"春季","leaf":true,"expanded":false,"children":[]}]}]


实体类设计:

public partial class TSeasonProduct
{
[JsonProperty("id")]
public int IIdExtension
{
get
{
return this.IId;
}
}

[JsonProperty("text")]
public string VcNameExtension
{
get
{
return this.VcName;
}
}

[JsonProperty("leaf")]
public bool BIsLeafExtension
{
get
{
//return this.BIsLeaf;
return this.Children.Count == 0;
}
}

[JsonProperty("expanded")]
public bool Expanded
{
get
{
return this.BIsLeafExtension ? false : true;
}
}

[JsonProperty("children")]
public List<TSeasonProduct> Children
{
get;
set;
}

}


我用的是Newtonsoft.Json 的序列化对象,生成json字符串。

JsonConvert.SerializeObject(obj, Formatting.None, new Newtonsoft.Json.Converters.IsoDateTimeConverter() { DateTimeFormat="yyyy-MM-dd HH:mm:ss"});


C#的Controller的ActionResult代码:

      /// <summary>
/// 产品接口
/// </summary>
/// <param name="id">请求参数</param>
public ActionResult Product(string id)
{
object objJson = base.SetError(this.output);
if (base.CurrentUser != null)
{
switch (id.ToLower())
{

#region 获取产品分类列表
case "listseason":
List<TSeasonProduct> lstSeasonProduct = this.productBusiness.GetSeason(0);
this.GetSeasons(ref lstSeasonProduct); // 调用递归的方法
objJson = lstSeasonProduct;
break;
#endregion

#region 添加产品分类
case "addseason":
try
{
string categoryName = Request["CategoryName"],
pId = Request["ParentId"];
int parentId = 0;
int.TryParse(pId, out parentId);

//插入数据库
int seasonId = this.productBusiness.CreateSeason(categoryName, parentId);
objJson = base.SetMessage(seasonId);
}
catch (ValidationException vex)
{
objJson = base.SetError(vex.Message);
}
catch (Exception ex)
{
objJson = base.SetError(ex.Message);
}
break;
#endregion

#region 编辑产品分类
case "editseason":
try
{
int seasonId = 0;
int.TryParse(Request["SeasonId"], out seasonId);
TSeasonProduct tSeason = this.productBusiness.GetSeasonByID(seasonId);
if (tSeason != null)
{
string seasonName = Request["SeasonName"];
bool flag = this.productBusiness.ModifySeasonById(seasonId, seasonName);
if (flag)
{
objJson = base.SetMessage(1);//编辑成功
}
else
{
objJson = base.SetMessage(0);//编辑失败
}
}
else
{
objJson = base.SetError("此产品分类不存在");
}
}
catch (ValidationException vex)
{
objJson = base.SetError(vex.Message);
}
catch (Exception ex)
{
objJson = base.SetError(ex.Message);
}
break;
#endregion

#region 删除产品分类
case "removeseason":
try
{
int seasonId = 0;
int.TryParse(Request["SeasonId"], out seasonId);
TSeasonProduct tSeason = this.productBusiness.GetSeasonByID(seasonId);
if (tSeason != null)
{
bool flag = this.productBusiness.RemoveSeasonById(seasonId);
if (flag)
{
objJson = base.SetMessage(1);//编辑成功
}
else
{
objJson = base.SetMessage(0);//编辑失败
}
}
else
{
objJson = base.SetError("此产品分类不存在");
}
}
catch (ValidationException vex)
{
objJson = base.SetError(vex.Message);
}
catch (Exception ex)
{
objJson = base.SetError(ex.Message);
}
break;
#endregion

default:
break;
}
}
else
{
objJson = base.SetError("您还没登录");
}

return Content(base.GenerateJson(objJson));
}


      /// <summary>
/// 递归查询产品分类列表
/// </summary>
/// <param name="list">父级产品分类列表</param>
private void GetSeasons(ref List<TSeasonProduct> list)
{
foreach (TSeasonProduct season in list)
{
List<TSeasonProduct> lstSeason = this.productBusiness.GetSeason(season.IId);
season.Children = lstSeason;
if (list.Count > 0)
{
GetSeasons(ref lstSeason);
}
}
}


第三步:设计TreePanel的展示

前台Html代码:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>产品分类管理</title>
<link href="/Content/resources/css/ext-all.css" rel="stylesheet" type="text/css" />
<link href="/Content/manager.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/Scripts/ext-base.js"></script>
<script type="text/javascript" src="/Scripts/ext-all.js"></script>
<script type="text/javascript" src="/Scripts/common.js"></script>
<script type="text/javascript">
Ext.onReady(function() {
Ext.QuickTips.init();
loadTreeCategory();
});

function loadTreeCategory() {
var loader = new Ext.tree.TreeLoader({
url: "/action/product/listseason"
});

var root = new Ext.tree.AsyncTreeNode({
id: '0',
text: "所有分类",
leaf: false,
loader: loader,
expandable: true,
expanded: true
});
var treeCategory = new Ext.tree.TreePanel({
id: "treeCategories",
animate: true,
enableDD: false,    /* 是否支持拖拽效果 */
allowDrag: false,
useArrows: false,
lines: true,
root: root,
listeners:
{
"contextMenu": function(node, e) {
var myContextMenu = new Ext.menu.Menu({
shadow: 'frame',
items: [{
iconCls: "button-add",
text: "添加",
scope: this,
handler: function() {
myContextMenu.hide();
Ext.MessageBox.prompt("添加产品分类", "名称:", function(button, text) {
if (button == "ok") {
if (Ext.util.Format.trim(text) != "") {
addCategory(node, text);
}
}
});
}
},
{
iconCls: "button-edit",
text: "编辑",
handler: function() {
myContextMenu.hide();
Ext.MessageBox.prompt("编辑产品分类", "名称:", function(button, text) {
if (button == "ok") {
if (Ext.util.Format.trim(text) != "") {
if (node.text != text) { /* 在修改值的情况下,请求处理 */
editCategory(node, text);
}
}
}
}, this, false, node.text);
}
},
{
iconCls: "button-delete",
text: "删除",
handler: function() {
myContextMenu.hide();
Ext.MessageBox.confirm("确认删除", "是否要删除指定内容?", function(button, text) {
if (button == "yes") {
removeCategory(node);
}
});

}
}
]
});

if (node.parentNode == null) {    /* 主根目录没有编辑和删除的功能 */
myContextMenu.items.get(1).setDisabled(true);
myContextMenu.items.get(2).setDisabled(true);
} else {
if (!node.isLeaf()) {
myContextMenu.items.itemAt(2).setDisabled(true);  /* 如果有子目录没有删除功能,根据需求而定(也可以设置删除功能) */
} else {
//myContextMenu.items.itemAt(0).setDisabled(true);
}

myContextMenu.items.itemAt(1).setDisabled(false);

}
e.preventDefault();

node.select(); //结点进入选择状态
myContextMenu.showAt(e.getPoint());
}
}
});

var panelCategory = new Ext.Panel({
title: "产品分类管理",
frame: true,
width: 300,
height:450,
autoScroll: true,
iconCls: "form-window",
items: treeCategory,
collapsible: false
});

panelCategory.render(document.body);
}

/* 添加分类 */
function addCategory(parentNode, text) {
var parentId = parentNode.id;

Ext.Ajax.request({
url: "/action/product/addseason", //请求的地址
method: "POST",
params: { CategoryName: text, ParentId: parentId }, //发送的参数
success: function(response, option) {
response = Ext.util.JSON.decode(response.responseText);
if (response.success > 0) {
createNode(parentNode, response.msg, text);
} else {
core.alert.error(response.msg);
}
},
failure: function(response, option) {
response = Ext.util.JSON.decode(response.responseText);
core.alert.error(response.msg);
}
});
}

/* 编辑分类 */
function editCategory(currentNode, text) {
Ext.Ajax.request({
url: "/action/product/editseason", //请求的地址
method: "POST",
params: { SeasonId: currentNode.id, SeasonName: text }, //发送的参数
success: function(response, option) {
response = Ext.util.JSON.decode(response.responseText);
if (response.success == 1) {
if (response.msg > 0) {
resetNode(currentNode, text);
} else {
core.alert.error("修改分类失败");
}
} else {
core.alert.error(response.msg);
}
},
failure: function(response, option) {
response = Ext.util.JSON.decode(response.responseText);
core.alert.error(response.msg);
}
});
}

/* 删除分类 */
function removeCategory(currentNode) {
Ext.Ajax.request({
url: "/action/product/removeseason", //请求的地址
method: "POST",
params: { SeasonId: currentNode.id }, //发送的参数
success: function(response, option) {
response = Ext.util.JSON.decode(response.responseText);
if (response.success == 1) {
if (response.msg > 0) {
removeNode(currentNode);
} else {
core.alert.error("删除分类失败");
}
} else {
core.alert.error(response.msg);
}
},
failure: function(response, option) {
response = Ext.util.JSON.decode(response.responseText);
core.alert.error(response.msg);
}
});
}

/* 创建一个TreeNode */
function createNode(node, id, text) {
var newNode = new Ext.tree.TreeNode({
id: id,
text: text,
draggable: false,
leaf: true
});

node.appendChild(newNode);
node.leaf = false;
//node.setIconCls('button-tree-folder-open');
node.expand();
}

/* 重置TreeNode的text */
function resetNode(node, text) {
node.setText(text);
}

/* 删除一个TreeNode */
function removeNode(node) {
var pNode = node.parentNode;
node.remove();
console.log(pNode);
var l = pNode.childNodes.length;
console.log(l);
if (l == 0) {
pNode.leaf = true;
//pNode.setIconCls('button-tree-leaf');
}
}
</script>
</head>
<body>
</body>
</html>


ok,页面运行起来的效果如图:



寄语:希望喜欢asp.net mvc 和 ExtJs 的朋友多多指点!  o(∩_∩)o
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐