【Lua】Lua + LWT + ExtJS构建目录树

  Lua处理后台逻辑,Lua lwt搭建后台程序,ExtJS根据后台传来的json数据构建目录树。



  前台html和ExtJS代码不用多讲,直接上代码:

  treePanel.html

 1 <html>
 2     <head>
 3         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 4
 5         <title>ExtJS TreePanel</title>
 6         <link rel="stylesheet" type="text/css" href="../../ext-5.0.0/examples/shared/example.css" />
 7
 8
 9         <script type="text/javascript" src="../ext-5.0.0/examples/shared/include-ext.js"></script>
10         <script type="text/javascript" src="../ext-5.0.0/examples/shared/options-toolbar.js"></script>
11
12         <script type="text/javascript" src="treePanel.js" charset="utf-8" ></script>
13
14     </head>
15     <body style=" margin: 0; padding: 0;">
16     </body>
17 </html>

  treePanel.js

 1 Ext.require(‘Ext.tree.Panel‘)
 2
 3 Ext.onReady(function(){
 4     Ext.Ajax.request({
 5         url: ‘treePanel.lua‘,
 6         method: ‘post‘,
 7         params: {
 8             id: "123",
 9             action: ‘getDir‘
10         },
11         success: function(response){
12             var text = response.responseText;
13             var obj = eval(‘(‘ + text + ‘)‘);
14             var treePanel = Ext.create(‘Ext.tree.Panel‘,{
15                 width: 200,
16                 rootVisible: false,
17                 store: obj,
18                 renderTo: Ext.getBody(),
19             });
20         },
21         failure: function() {
22             Ext.Msg.alert("失败","失败了");
23         }
24     });
25 });

  在treePanel.js中,通过后台传递过来的json字符串无法直接使用,需要将其转化为json对象才可以作为treePanel的数据源。

  转换方法:jsonObj = eval(‘(‘+jsonString‘+)‘)



  接下来是逻辑处理部分,也就是遍历目录数据的部分。

  一开始我使用的方法是先将所有文件path遍历至一个table内,然后处理table将其转化为treePanel可以用的json格式,这样遍历过程比较简单,不过处理过程太过繁琐,处理方法结构脆弱且BUG不断,效率也是惨不忍睹。最后还是放弃了。

  其实最合适的方法是直接在遍历时就生成所需要的json格式,好吧,现在就来实现他:

  lua遍历目录需要达成的格式为:

 1 local s = {root = {
 2         text = "rootNode",
 3         expanded = true,
 4         leaf = false,
 5         children = {
 6             {
 7                 text = ‘book1‘,
 8                 leaf = false,
 9                 children = nil
10             },
11             {
12                 text = "book2",
13                 leaf = false,
14                 expanded = true,
15                 children = {
16                     {
17                         text = "con1",
18                         leaf = false,
19                         children = {
20                           {
21                             text = "ccc1",
22                             leaf = true
23                           }
24                         }
25                     },{
26                         text = "con2",
27                         leaf = true
28                     }
29                 }
30             },
31             {
32                 text = "book3",
33                 expanded = true,
34                 leaf = true
35             }
36         }
37     }
38 }

  用lfs模块提供的方法遍历目录,并创建一个table,操作table使之成为这样的结构。其中:

    "leaf = true"表示这个节点是一个文件,所以不必加上"children = {}"属性;

    如果节点是一个文件夹,那给节点设置"leaf = false"表示为文件夹(如果不设置这个属性默认为文件夹,不过这里用来作为判断的条件,所以加上),并且加上"children = {}" 用来作为该文件夹下文件的根节点。

  方法getDirTable(filePath)用以遍历目录,并生成指定的table结构数据:

 1 function getDirTable(filePath)
 2     local table = {root = {text = "rootNode", leaf = false, children = {}}}
 3     function getDir(path,table)
 4         for file in lfs.dir(path) do
 5             if file ~= "." and file ~= ".." then
 6                 p = path .. "/" .. file
 7                 if isDir(p) == "directory" then
 8                     local node = {text = file, leaf = false, children = {}}
 9                     table[#table + 1] = node
10                     local nObj = table[#table].children
11                     local nPath = path .. file .. "/"
12                     getDir(nPath, nObj)
13                 else
14                     local node = {text = file, leaf = true}
15                     table[#table + 1] = node
16                 end
17              end
18         end
19     end
20     getDir(filePath,table.root.children)
21     return table
22 end

  其中遍历了当下文件夹,如果文件夹下存在子文件夹,则递归遍历子文件夹,并且将子文件夹下的文件和文件夹依照规则添加到该文件夹节点的"children = {}"内。

  在这个方法中,还有一个辅助方法,用来判断path是文件还是文件夹:

1 function isDir(path)
2    return lfs.attributes(path).mode
3 end

  获取目录遍历table后,使用cjson方法转换为json字符串:

1 function table2Json(table)
2     local cjson = require("cjson")
3     return cjson.encode(table)
4 end

  最后通过lwt将json字符串传到前台:

1 httpd.set_content_type("text/json")
2 if request.method == "POST" then
3     if args.action == "getDir" then
4         httpd.write(table2Json(getDirTable(request.filedir)))
5     end
6 elseif request.method == "GET" then
7     httpd.write("是个字符串")
8 end

  完整代码:

 1 require "lfs"
 2 require "httpd"
 3
 4 request, args = ...
 5
 6 function isDir(path)
 7    return lfs.attributes(path).mode
 8 end
 9
10 function table2Json(table)
11     local cjson = require("cjson")
12     return cjson.encode(table)
13 end
14
15 function getDirTable(filePath)
16     local table = {root = {text = "rootNode", leaf = false, children = {}}}
17     function getDir(path,table)
18         for file in lfs.dir(path) do
19             if file ~= "." and file ~= ".." then
20                 p = path .. "/" .. file
21                 if isDir(p) == "directory" then
22                     local node = {text = file, leaf = false, children = {}}
23                     table[#table + 1] = node
24                     local nObj = table[#table].children
25                     local nPath = path .. file .. "/"
26                     getDir(nPath, nObj)
27                 else
28                     local node = {text = file, leaf = true}
29                     table[#table + 1] = node
30                 end
31              end
32         end
33     end
34     getDir(filePath,table.root.children)
35     return table
36 end
37
38 httpd.set_content_type("text/json")
39 if request.method == "POST" then
40     if args.action == "getDir" then
41         httpd.write(table2Json(reTable(getDirTable(request.filedir))))
42     end
43 elseif request.method == "GET" then
44     httpd.write("GET请求")
45 end

  访问treePanel.html

  这里有一个问题,看asd.sda文件夹下

  这里出现了一个没有名字的空文件夹。这是由于遍历时,检测到是目录时默认给其赋值了"children = {}"的缘故,由于在treePanel中,当不设置"leaf: true"时,默认leaf为false,即将其认为是一个文件夹。所以ExtJS给这个文件夹节点添加了一个没有名字的空子文件夹。

  要解决这个问题,只要将为空的文件夹设置为children = nil,这样就可以了。

 1 function reTable(table)
 2     local obj = table.root.children
 3     function re(obj)
 4         if #obj == 0 then
 5             obj = nil
 6         else
 7             for i = 1, #obj do
 8                 if obj[i].leaf == false then
 9                     if #(obj[i].children) == 0 then
10                         obj[i].children = nil
11                     else
12                         re(obj[i].children)
13                     end
14                 end
15             end
16         end
17     end
18     re(obj)
19     return table
20 end

  最后把lwt响应改一下:

httpd.write(table2Json(reTable(getDirTable(request.filedir))))

  看看效果:

  这样就显示了一个空文件夹,问题解决!

时间: 2024-11-06 03:14:02

【Lua】Lua + LWT + ExtJS构建目录树的相关文章

【Lua】LWT遍历指定目录并输出到页面中

首先用lua遍历目录: 1 function getDirs(path) 2 local s = {} 3 function attrdir(p) 4 for file in lfs.dir(p) do 5 if file ~= "." and file ~= ".." then 6 local f = p .. file 7 local attr = lfs.attributes (f) 8 if attr.mode == "directory"

js实现目录树

第一步:HTML结构 1 <div class="folderDiv"> 2 <p>目录</p> 3 <ul class="folder"></ul> 4 </div> 第二步:CSS样式 1 /*目录树*/ 2 .folderDiv {width: 14%;float: left;height: auto;overflow: auto;border:1px solid #ccc;border-

【Lua】LWT后台用JSON与 ExtJS传递数据

要完成目录树的构建,需要前台ExtJS构筑页面,后台处理逻辑,中间由JSON传递数据. 首先搭建后台环境: 1 require "httpd" 2 require "lfs" 3 4 request, args = ... 5 6 local s = {root = { 7 text = "rootNode", 8 expanded = true, 9 children = { 10 { 11 text = 'book1', 12 leaf =

JS动态构建一棵目录树

JS动态构建一棵目录树 在使用frameset布局的时候,经常会用到目录树,我们可以把一棵树写死,但是更多的情况是,这棵树需要随时被改动,所以我们期望的是他能够被动态的构建. MVC,算是了解一点,那本文就把这棵树根据M-V-C给拆开分解吧. 点击链接demo→ 下面就来看看这棵树是怎么构建的. Module [数据层] var tree = { "id": 0, "a1": { "id": 1, "name": "

Vue组件之无限级目录树构建

渐渐,了解Vue也有一个月了,最近遇上个无限级目录树的小功能,为了能多学习避免自己操作dom或是网上下插件,下决心用Vue来解决当下问题,毕竟毛爷爷讲过,实践出真知,本次主要运用了组件之间的相互循环引用,然后就是循环组件与父组件之间的通信, 源数据格式采用了毗邻结构转为多维数组的形式,没办法,我也暂且只能想到这样去做,学习革命任重道远....... 1 Vue.component('item',{ 2 template:'<ul> 3 <li v-for="child in m

从Chrome源码看浏览器如何构建DOM树

.aligncenter { clear: both; display: block; margin-left: auto; margin-right: auto } p { font-size: 15px; text-indent: 2em } #colorbox.crayon-colorbox,#cboxOverlay.crayon-colorbox,.crayon-colorbox #cboxWrapper { position: absolute; top: 0; left: 0; z-

HBase 在HDFS 上的目录树

总所周知,HBase 是天生就是架设在 HDFS 上,在这个分布式文件系统中,HBase 是怎么去构建自己的目录树的呢? 这里只介绍系统级别的目录树. 一.0.94-cdh4.2.1版本 系统级别的一级目录如下,用户自定义的均在这个/hbase 下的一级子目录下 /hbase/-ROOT- /hbase/.META. /hbase/.archive /hbase/.corrupt /hbase/.hbck /hbase/.logs /hbase/.oldlogs /hbase/.snapshot

HBase在HDFS上的目录树

众所周知,HBase 是天生就是架设在 HDFS 上,在这个分布式文件系统中,HBase 是怎么去构建自己的目录树的呢? 这里只介绍系统级别的目录树: 一.0.94-cdh4.2.1版本 系统级别的一级目录如下,用户自定义的均在这个/hbase 下的一级子目录下 /hbase/-ROOT- /hbase/.META. /hbase/.archive /hbase/.corrupt /hbase/.hbck /hbase/.logs /hbase/.oldlogs /hbase/.snapshot

dTree无限级目录树和JQuery同步Ajax请求

以前都是用JQuery对树的支持来实现目录树的,近来闲来无事就弄了下dTree,感觉其无限级目录还是挺好的,而且它的使用也比较方便,基本上就是先把要用的js文件即dtree.js和css文件dtree.css引入,另外就是它默认的图片,当然这些图片都是可以自己指定的,它的css样式也可以自己改变的! 关于dTree就先谈谈它的node,dTree的node的构造方法可以指定下列参数, Js代码 id //唯一标识,数字型 pid//父节点的id,如果是根结点那就只能是-1,一般来讲只有一个最顶层