jQuery 学习第六课 实现一个Ajax的TreeView |
本文标签:Ajax,TreeView 最终实现的效果是一个目录文件查看器,如图所示: ![]() 其原理是,当用户单击一个目录的时候,将这个目录的路径发送给服务器端,服务器端返回这个目录中的文件和目录信息 。在服务器端,定义一个如下的类来表示要传递的文件信息: 复制代码 代码如下: public class FileInformation { public string FullPath { get; set; } public string Name { get; set; } public string Info { get; set; } public bool IsFolder { get; set; } } 其中FullPath是文件的完整路径,用于获取它的子文件夹/文件用,Name是文件的名字,用于显示,IsFolder是区分这条数据是一个文件还是文件夹,以便用不同的图标来显示,最后一个Info是一些附加信息,在此例中没有用到 。根据一个路径获得目录中的文件信息的C#代码很简单,顺便就贴在这里: 复制代码 代码如下: public class FileManager { public static List<FileInformation> GetFolderContent(string fullpath) { List<FileInformation> res = new List<FileInformation>(); DirectoryInfo info = new DirectoryInfo(fullpath); if (info.Exists) { foreach (DirectoryInfo d in info.GetDirectories()) { res.Add(new FileInformation { FullPath = d.FullName, Name = d.Name,IsFolder = true, Info = "Any More Information goes here" }); } foreach (FileInfo f in info.GetFiles()) { res.Add(new FileInformation { FullPath = f.FullName,Name = f.Name,IsFolder = false, Info = "Any More Information goes here" }); } } return res; } } 此例中采用JSON数据的格式来传递这些信息 。因此要将这些数据序列化 。在.Net 3.5中,有现成的将实体类序列化成JSON数据的类,使用方法如下 复制代码 代码如下: public static string ToJson<T>(T obj) { DataContractJsonSerializer d = new DataContractJsonSerializer(typeof(T)); System.IO.MemoryStream ms = new System.IO.MemoryStream(); d.WriteObject(ms, obj); string strJSON = System.Text.Encoding.UTF8.GetString(ms.ToArray()); ms.Close(); return strJSON; } 如果是.net 2.0,则可以寻找一些第三方的组件,自己写一个也不麻烦 。 至此,服务器端的主要工作已经完成了 。新建一个Genric Handler文件,filelist.ashx,代码如下,简单的响应下请求,输出数据即可: 复制代码 代码如下: public class FileList : IHttpHandler { public void ProcessRequest (HttpContext context) { string path = context.Request.QueryString["path"]; string data = JsonHelper.ToJson<List<FileInformation>>(FileManager.GetFolderContent(path)); context.Response.Write(data); } public bool IsReusable { get { return false; } } } 下面考虑客户端html代码的编写 。最主要的就是两个事件,也就是鼠标点击发送ajax请求,处理返回的json数据生成html代码,鼠标再次点击将html代码清空 。在这里,采用ul li来显示这个treeview,在li中有一个不可见的span,里面包含了文件完整的路径,它将用作发起ajax请求的参数,但是对用户是不可见的 。 HTML代码很简单,就4行: 复制代码 代码如下: <body> <ul> </ul> </body> 首先需要初始化一个根目录,例如D:,代码如下: 复制代码 代码如下: $(function() { $(<li class="folder">D:\\<span class="fullpath">D:\\</span></li>).appendTo(ul); $(li).hover(function() { $(this).css(cursor, pointer); }, function() { $(this).css(cursor, default); }); $(li.folder).toggle(LoadFile, CloseFolder); }); 构造好一个li结点,添加到ul中去,然后设置下鼠标动作的样式,最后为其绑定事件处理程序,LoadFile和CloseFolder 。 复制代码 代码如下: function LoadFile(event) { if (this == event.target) { var path = $(this).find(span).html(); var node = $(<ul>); $(this).append(node); $.getJSON(filelist.ashx, { path: path }, function(data) { $.each(data, function() { if (this.IsFolder) { node.append($(<li>).addClass(folder).html(this.Name).append($(<span>).addClass(fullpath).html(this.FullPath))); } else { node.append($(<li>).addClass(file).html(this.Name).append($(<span>).addClass(fullpath).html(this.FullPath))); } }); node.find(li.folder).toggle(LoadFile, CloseFolder); }); } } 首先要判断event的target和this是否是同一个对象,以避免点击子节点事件浮升的时候造成多次触发 。首先利用find和html函数获得完整的路径 。构造好一个ul节点并把它添加到当前的li中 。此时ul是空的,接下来发起ajax请求,获得服务器端的数据 。对每条数据生成一个li,其中对于是否是目录加以判断,生成带有不同class的li,再加到node中 。最后,不要忘记为新增的节点也绑定事件处理程序 。代码还是比较简单的,至于关闭目录节点的代码就更加简单了, 复制代码 代码如下: function CloseFolder(event) { if (this == event.target) $(this).find(ul).remove(); } 至此此范例已经完成了 。还少了几句css,不再列出 。 这个例子实现的功能和样式都比较粗糙,不过在此基础上做更多的扩展和美化已经不是难事 。例如可以加上一点现成的动画效果: 复制代码 代码如下: function CloseFolder(event) { if (this == event.target) { var node = $(this).find(ul); node.hide(slow, function() { $(this).find(ul).remove(); }); } } 先隐藏,再删除 。类似地,可以加载完毕后立刻隐藏,再淡出 。 |