`
阅读更多
[size=medium]3.1. 真的,我是为了树,才开始学ext的。

之前使用过xtree和dojo中的tree,感觉都是怪怪的,界面简陋,功能也不好上手,待看到ext里的树形真是眼前一亮,在此之前,动态增
添,修改删除节点,拖拽和右键菜单,我一直认为是不可能实现的任务,而在ext上却轻松实现了,而且界面和动画效果相当完美。真是让人爱不释手啊。

树形是非常典型的一种数据结构,多级菜单,部门组织结构,省市县三级这种金字塔结构都可以用树形表示,要表示一个老爸有一帮孩子的情况真是非树形莫属啊,做好了这部分,绝对是个亮点。



靠,这是树吗?

嗯,现在的确不太像树,因为它只有一个根。

靠,我们要的是树,你就搞出一个根来,有鸟用啊。

嗯,理论上等它自己发芽长成树,可能性是比较小,不如咱们偷偷插上几个枝子,说不定看起来就更像树了。

[align=middle[/img]

咦?它怎么还是这么点儿东西?客官莫急,待小二儿给你整治一番,即看庐山真面目。

[img]http://203.93.254.59:8889/extdoc/shared/images/03-03.png" alt="" align="middle[/img]

嗯,现在的确有点儿意思了,不过它开始的时候就那么缩在一团,看着很不爽,每次都要点这么几下才能看到底下的东西,咱们有没有办法让它每次渲染好就自己展开呢?

方法当然有咯,请上眼。

root.expand(true, true);
这一下就能解您燃眉之急,第一个参数是说,是否递归展开所有子节点,如果是false,就只展开第一级子节点,子节点下面还是折叠着的,。第二个参数是说是否有动画效果,true的话,你可以明显看出来那些节点是一点儿点儿展开的,否则就是刷拉一下子就出来了.

为了方便,咱们的例子里直接就可以展开了,省的再去点啊。1.x的例子在lingo-sample/1.1.1/03-02.html。


[align=middle[/img]

好了,看了这些例子,应该对树型有些认识了,虽然这里只有TreeNode,却能表示枝杈或者叶子,原理很简单,如果这个TreeNode下有其他
节点,它就是一个枝杈,如果没有,它就是一个叶子,从它前头的图标就很容易看出来。嘿嘿,根其实就是一个没有上级节点的枝杈了。实际上,他们都是
TreeNode而已,属性不同而已。

2.0的例子在lingo-sample/2.0/目录下,分别是03-01.html和03-02.html。


3.5. 这种装配树节点的形式,真是让人头大。




如此刀耕火种不但麻烦,而且容易犯错,有没有更简便一些的方法吗?答案是利用Ext.tree.TreeLoader和后台进行数据交换,我们在只提供数据,让TreeLoader帮咱们做数据转换和装配节点的操作。

啦啦啦,json和ajax要登场了,不过你是否还记得我说过,一旦涉及到ajax就需要配合服务器了,ajax是无法从本地文件系统直接取得数据的。

首先,让我们为TreePanel加上TreeLoader

var tree = new Ext.tree.TreePanel('tree', {
    loader: new Ext.tree.TreeLoader({dataUrl: '03-03.txt'})
});
在此,TreeLoader仅包含一个参数dataUrl: '03-03.txt',这个dataUrl表示,在渲染后要去哪里读取数据,为了方便模拟,我们写了一个txt文本文件提供数据,直接打开03-03.txt可以看到里边的内容。

[
    {text:'not leaf'},
    {text:'is leaf',leaf:true}
]
里边是一个包含了两个节点定义的数组,可能你会发觉那个多出来的属性leaf:true,它的效果很神奇,这一点我们马上就可以看到。

如果你现在就去匆匆忙忙的刷新页面,想看一下咱们的成果,那一定会失望而归,页面上没有像你期待的那样,从03-03.txt读取数据,显示到页面
上,你依然只能看到那个孤零零的根。这是因为TreeNode是不支持ajax的,我们需要把根节点换成AsyncTreeNode,它可以实现咱们的愿
望。

var root = new Ext.tree.AsyncTreeNode({text:'偶是根'});
[img]http://203.93.254.59:8889/extdoc/shared/images/03-05.png" alt="" align="middle[/img]

估计谁第一次看到这场面都一定吓傻了。我们不是只定义了两个节点吗?怎么一下子跑出这么多东西来?先别着急,让我们先把root.expand(true, true)改成root.expand(),避免节点无限展开下去,然后慢慢研究这个情况。

[img]http://203.93.254.59:8889/extdoc/shared/images/03-06.png" alt="" align="middle[/img]

现在场面被控制住了,取消了递归展开,只展开根节点的第一层节点,我们得到的确实是与03-03.txt文件里相对应的两个节点,不过这两个节点有些不同,not leaf节点的图标赫然是枝杈的图标,如果点击它前面的加号,便又成了上面的场景。Why?

原因就来自AsyncTreeNode,这个东西会继承根节点TreeLoader中dataUrl,你点展开的时候,会执行这个节点的
expand()方法,ajax会跑到dataUrl指定的地址去取数据,用firebug可以看到当前节点id会作为参数传递给dataUrl指定的地
址,这样我们的后台就可以通过这个节点的id计算出该返回什么数据,得到了数据TreeLoader去解析数据并装配成子节点,然后显示出来。

哈哈,现在就是关键部分了。因为咱们使用的03-03.txt提供的数据,不会判断当前节点的id,所以每次返回的数据都是一样的,这就是树会无限循环下去的原因了。

那么为啥只有第一个节点会无限循环下去呢?第二个节点就没有那个小加号,呵呵~因为第二个节点不是AsyncTreeNode
,TreeLoader在生成节点的时候会判断数据里的leaf属性,如果是leaf:true,那么就会生成TreeNode而不是
AsyncTreeNode,TreeNode可不会自动去用ajax取值,自然就不会无限循环展开了。

现实中,异步读取属性的节点是很爽的一件事情,因为你可能要保存成千上万条节点记录。一次性全部装载的话,无论读取和渲染的速度都会很慢。使用异步
读取的方式,只有点击某一节点的时候,才去获得子节点属性,并进行渲染,极大的提高了用户体验。而且ext的树形本身有缓存机制,打开一次,再点击也不会
去重复读取了,提升了响应速度。

html例子,1.x版本在lingo-sample/1.1.1/03-03.html,2.0版本在lingo-sample/2.0/03-03.html。

为了巩固学习效果,咱们再写一个json获得数据的例子,这次的json稍微写复杂一点儿。

[img]http://203.93.254.59:8889/extdoc/shared/images/03-07.png" alt="" align="middle[/img]

这次对应的json数据文件是03-04.txt。

[
    {text:'01',children:[
        {text:'01-01',leaf:true},
        {text:'01-02',children:[
            {text:'01-02-01',leaf:true},
            {text:'01-02-02',leaf:true}
        ]},
        {text:'01-03',leaf:true}
    ]},
    {text:'02',leaf:true}
]
这也可以看作是在数据不多的情况下,一次加载所有数据的途径,只要确保所有叶子节点上都加上leaf:true的属性,就不会出现循环展开的问题了。

html例子:1.x在lingo-sample/1.1.1/03-04.html,2.0在lingo-sample/2.0/03-04.html。

[/size]
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics