对“打造基于jQuery的高性能TreeView”的扩展

园子里的牛人,真是特别多,不得不让人佩服。很多又酷又帅的效果拿过来略作修改就可以用,爽之余还真得感谢他们的无私奉献。 

     话说今天看到了一个TreeView 效果真是帅呆了,截个图如下:

      

    该博客的地址:http://www.cnblogs.com/xuanye/archive/2009/10/26/1590250.html

    博主是:假正经哥哥

    大家没有看的可以先去看一下。

从看到这个效果的那刻起,我就深深的被它吸引。自己平时很多的地方其实也是可以用到TreeView的,但因为自己做出来的东西自己都很不爽,所以一般的尽量用 DropDownList来处理类似的效果,虽说没有这个树好看,但开发起来比较快。我把作者的代码和jscss、图片 一个一个的拿下来,自己运行,感觉真的很爽,而看他的代码,是通过一个json的对象来填充数据项。既然这样,那我能不能在服务器端生成相应的json 呢?如果生成成功的话,那不是就可以轻松的把这种很酷的东西用到自己的项目中了?? 之前看过老赵的在服务器生成客户端验证的做法,很符合自己的想法,今天我也来试试,通过在服务器端生成的相应的数据来使用该牛人的树形控件:)。

首先说一下:这个控件还是原作者的(如果有版权也是他的),甚至客户端的代码都基本不用修改动,我要做的是轻松生成相应的数据。废话不说了,开始吧: 

第一步:设计树节点类

根据原文 js 代码中的 json 格式进行分析,我想使用一个类来表示这个json 的,类的设计如下:

TreeItem

 

类很简单,大家看代码就明白了。为了模拟json的嵌套结构,在类中使用了一个 List<TreeItem> ChildNodes 来实现这种嵌套。

 

第二步:为类添加相应的方法

要把类和成json 字符串,最简单的方法是使用 System.Web.Script.Serialization 命名空间中的 JavaScriptSerializer 类,知道这些就很简单了,我们为类 TreeItem 添加一个 ToJsonString() 的公有方法,代码如下: 

Code

为了测试结果是否正确,可以写一个模拟测试的方法,看其输出。方法很简单,为了避免凑字之嫌,就不帖出来了,测试后生成的结果如下:

 

基本上和原文要求的json格式一致。但也发现了一个问题,当TreeView 类中 List<TreeItem> ChildNodes 没有数据时,添加子节点会出现 空引用的错误 ,如果在构造函数中先 new 一下的话,不会报错,但生成的 json 中 ChildNodes为[],而原来要求的是:ChildNodes:null。这个问题很好办:加上一个方法,来添加子节点,如果子节点没有分配内存,则先分配后添加,这样可以保证有子项时不会报错,没有子项时能生成 null.方法代码如下:

    

Code

 

第三步:开始使用TreeView显示用服务器端生成的数据

好了,现在我们试试添加一个“一般处理程序”来生成相应的json子句。

添加 GetTreeData.ashx 代码如下: 

 

ProcessRequest

代码中当  I 模 3余 2时,模拟生成了一些二级子项目。为的是能看到多级时的效果。

把原作者的代码修改一下,将原来引用json数据的代码改为引用我们生成的数据: 

   <!-- <script src="SampleData/tree2.js" type="text/javascript"></script> -->

    
<script src="Handler/GetTreeData.ashx" type="text/javascript"></script>

  

    其他的都不用改动,运行程序后,看到效果如下: 

           

 

至此,已经可以通过 一句“context.Response.Write(tdata.ToJsonString());”来使用这个酷树了。 

看看是不是很简单的就可以重用了? 

当然了,如果仅仅只是这样,也不算是什么扩展了,后面还会继续扩展,以使其他更适合更方便我们使用。

 

第四步:选中荐的扩展

    在平时的使用中,经常要对树的选中项进行修改,这个时候就要先把原来选中的显示出来,我们为了方便在服务器端构造的json 能显示已经选中项,所以第一个扩展就是要增加一个选中项的方法。当然想这个方法时,为了能忠实的还原选项,我先写了一个方法,然后再对其进行了三次重构,以保证能正确的选中项,而且还能正确的还原上级节点的选中状态,过程就不多说了, 上代码:

 

SelectItem

 

说明一下:公有方法,只需要传入id数组就行了,两个重载的私有方法辅助选中项。还原时要注意的是:父项被选中,则所有的子项都选中,子项都没有选中则父项也不选中,子项有选中,但没有全选,则父项是半选状态。

现在我们修改 GetTreeData.ashx 中的代码,来实现选项还原:       

 

Code

 

效果:

 

看就这么一句 tdata.SelectItem(new int[] {2,3,4,5,6,7,8 }); 是不是很方便?

 

第五:对从数据库的取数据扩展

 

在平常的项目中,城市分级,商品类别分级、目录结构等,以及部门等都需要这样的数据树来达到直观的显示效果,现在我们以从级分类为例子,从数据库读取数据,并生成相应的json 数据。当然了,你每次要用到时候都象上面那样写也行,如果要想重用,并且使用时候修改尽量的少,那么最好是进行扩展。

在我们的项目中,用到较多的多级分类列表的数据表设计基本都差不多,在这里我们设计一个简单的但常见的表结构来存放分类数据,并最终实现从数据库中提取数据并生成需要的 json 数据。

数据表脚本如下:

 

 

Code

 

为了直观,截个图:

 

 

1、 先建立一个静态类,来扩展TreeItem类:   

public static class TreeItemHelper
{

}


2、 添加扩展方法:    

Code

 

这是一个递归的方法,很简单。当然在调用时,我们可以更简单一点,因为第一级的分类的父ID都是从0开始的(呵呵我的这个表的逻辑是这样的:)),而且我们只需要传入 DataTable 就行了,所以我们重载一下: 

Code

3、 使用

我们添加一个新的处理程序 GetTreeDataFromDB.ashx ,并在其中添加如下代码:

 

Code

 

4、 效果:

数据表中数据截图: 

运行效果截图:

 

当然了,如果数据结构不一样,那么只需要简单的修改一下服务器端的代码就行了,丝毫可以不用去改到客户端的代码,就能达到完美的复用。 

写到这里,突然想到了一点,也许这个以后在其他的项目中还要重用,为了能够快速的回忆起这个类怎么使用,以及数据表脚本是怎么样的,我做的服务基本上都会有一个 Help()方法,用来告诉用户这个类是干什么用的,或是怎么用。这样既可以备忘,又可以在别人使用这个类时不用看源代码就能很好的使用。做法很简单,我们再扩展两个方法,以备不时之需:

 

 

Code

 

这样以后要重建表,就可以很方便的使用 ti.GetTableSql()获得表结构的脚本。

更有甚者,你可以在第一次使用时,检测有没有应相应的数据库表支持,没有而自动生成相应的表。具体的就不多写了,

 

最后感慨一下,写东西真累啊,所以还想再一次感谢 那位假正经哥哥的辛苦劳动和无私分享!以后都受用了。

 

附:原代码-TreeView.rar

开发运行环境:win7 + IE8 + VS2008 + SQL2008

 

posted @ 2009-10-27 18:23  Jun@似水流年  阅读(4814)  评论(33编辑  收藏  举报