我在网上见过几篇关于MVC和jsTree的好教程,但是它们多少有些过时了,不适用于jsTree的最新版本(它是免费的)。我想把我使用jsTree的经验发上来有一段时间了(对于不知道什么是jsTree的朋友,请来这看看:www.jsTree.com)。还有什么比通过实现一个简单的文件管理器更好的分享这些经验呢?
在这篇文章里,我将关注jsTree两方面的问题。首先是挺打击我的是通过插话移动树结点 的可能性,就像Windows资源管理器一样。另一个我不想涉及到的功能(但是已经包括在代码中了)是使用鼠标右键显示上下文菜单并且从那创建目录、重命名等等。我将不会在这篇文章里发布一个包括重命名、剪切和复制功能的完整解决方案,因为这仅做为如何使用jQuery和MVC的一个起点。
图1:
开始写代码
第一步,我们将使用一种特殊的格形式把我们的树定义成JSON类。
public class JsTreeModel { public string data; public JsTreeAttribute attr; public string state = "open"; public List<JsTreeModel> children; } public class JsTreeAttribute { public string id; }
在data属性里要存储树的标题,在ID属性里存储完整路径。树的最初状态要展开所有的叶子结点,也就是"open“所代表的意思。
我们将使用递归方法填充树,这其实并不复杂。
绑定树
我们将使用JavaScript代码绑定树。
$('#MainTree').jstree({ "json_data": { "ajax": { "url": "/Home/GetTreeData", "type": "POST", "dataType": "json", "contentType": "application/json charset=utf-8" } }, "themes": { "theme": "default", "dots": false, "icons": true, "url": "/content/themes/default/style.css" }, "plugins": ["themes", "json_data", "dnd", "contextmenu", "ui", "crrm"] });public class JsTreeAttribute{ public string id;}
正如我们已经知道的,”dnd"代表“拖放”。
如下代码完成拖放操作:
$('#MainTree').bind("move_node.jstree", function (e, data) { data.rslt.o.each(function (i) { $.ajax({ async: false, type: 'POST', url: "/Home/MoveData", data: { "path": $(this).attr("id"), "destination": data.rslt.np.attr("id") }, success: function (r) { Refresh(); } }); }); });
在控制器端,我们必须使用:
[HttpPost] public ActionResult MoveData(string path, string destination) { // get the file attributes for file or directory FileAttributes attPath = System.IO.File.GetAttributes(path); FileAttributes attDestination = System.IO.File.GetAttributes(path); FileInfo fi = new FileInfo(path); //detect whether its a directory or file if ((attPath & FileAttributes.Directory) == FileAttributes.Directory) { if((attDestination & FileAttributes.Directory)==FileAttributes.Directory) { MoveDirectory(path, destination); } } else { System.IO.File.Move(path, destination + "\\" + fi.Name); } AlreadyPopulated = false; return null; }
我不得不找其他的方法去移动目录,因为微软的“Directory.Move"并不能运行在所有的情况。再这,这只是一个初级教程,还并不想把它做成完整教程。
兴趣点
一个惹人烦的地方是在每一次任务之后都要刷新树(如移动、创建目录),这是我找到的同步磁盘和树的唯一方法。如果只是存储叶子的名字, 或许某个MVP可以帮助我。我必须要使用会话状态变量,因为假设我点击了树的最后一个叶子结点,将会使整个数再填充一遍。对此我还无法解决。