最近完成了一个可以拖拽的异步按需加载树,顾名思义,这个树,至少支持以下三个功能。
1,节点可以拖拽(项目需要,已设置为只允许同级节点拖拽)。
2,异步加载(使用ajax加载数据,没啥好说的)。
3,按需要加载(点击展开按钮时,加载所需数据,不点击不加载,最小化的加载数据,最大化的支持大数据,哈哈)。
下面就这三个功能,分别贴出关键代码。
一,节点可以拖拽需要添加的代码。
1,先对树型控件的setting变量增加如下属性,并添加dropPrev,dropInner,dropNext方法,具体方法内容,请点击后面demo中网址右键。
edit: { enable: true, showRemoveBtn: false, showRenameBtn: false, drag: { autoExpandTrigger: true, prev: dropPrev, inner: dropInner, next: dropNext } }
2,在callback属性中加载如下代码,并分别新建两个方法beforeDrag和beforeDrop
callback: {
beforeDrag: beforeDrag,
beforeDrop: beforeDrop
}
至此拖拽功能基本实现,详细代码请自行扒下。
二:异步加载(使用ajax加载数据,没啥好说的),代码略。
三:按需要加载(点击展开按钮时,加载所需数据,不点击不加载)
1,在callback属性中加载如下代码,并新建方法beforeExpand,为什么是beforeExpand而不是onExpand呢,是因为在这个树中,预加载比加载完成后显示效果好。
callback: {
beforeExpand: beforeExpand
}
并且这里有个小技巧:若节点存在子节点,就让其前面以文件夹图标显示,方法如下。
public string GetList()
{
string parentId = RequestExtension.GetForm<String>("parentId", "");
if (String.IsNullOrEmpty(parentId))
{
parentId = new Guid().ToString();
}
StringBuilder treeSb = new StringBuilder("[");
var list = fileTypeRepository.GetFileTypeByParentId(new Guid(parentId));
foreach (var item in list)
{
treeSb.Append(string.Concat("{'id':'", item.ID, "'"));
treeSb.Append(string.Concat(",'name':'", item.TypeName.Trim(), "'"));
var childList = fileTypeRepository.GetFileTypeByParentId(item.ID);
if (childList.Count > 0)
{
treeSb.Append(",'isParent':true");
}
else
{
treeSb.Append(",'isParent':false");
}
treeSb.Append("},");
}
return String.Concat(treeSb.ToString().TrimEnd(','), "]");
}
这里如果有子节点,不管多少,虚加载一个名字为本人名字的节点,当然这个子节点在父节点展示时,自然会被干掉,同时真正的节点加载进来,并同时判断这一级节点是否有子节点,代码如下:
function beforeExpand(treeId, treeNode) { if (treeNode.children) { for (i = 0; i < treeNode.children.length; i++) { zTree.removeNode(treeNode.children[i]); } } if (treeNode.children) { for (i = 0; i < treeNode.children.length; i++) { zTree.removeNode(treeNode.children[i]); } } $.post("/Ashx/FileType.ashx?action=GetList", { parentId: treeNode.id }, function (txt) { var childNodes = eval(txt); for (i = 0; i < childNodes.length; i++) { var newNode = { id: childNodes[i].id, name: childNodes[i].name, children: childNodes[i].children, childOuter: false }; addTreeNode(treeNode, newNode); } }, "text"); return (treeNode.expand !== false); }
这里判断清除children用了两次,不得已,因为只清除一次,有子节点的节点不会被清除,所以需要清除两次,若是有人有更好的办法,一次就清除,不吝赐教。
(找到问题的原因了,清除子节点的代码应该改为:
var childCount = treeNode.children.length; for (i = 0; i < childCount; i++) { zTree.removeNode(treeNode.children[0]); }
这段代码有意思,呵呵。2月16号备注。
)
至此,一个可以拖拽的异步按需加载树就基本完成,当然这个树,还不只这点功能,比如右键增加、删除节点,比如修改节点等等,都一一实现,更多效果,请查看demo网址:http://www.qicheba.net/FileManage/TypeManage
如果觉得有用,请猛击推荐,谢谢。
备注:这个Demo使用了一款功能强大的树型控件,名字叫:zTree,官网地址:http://www.ztree.me/v3/demo.php#_101