ExtJs十二(ExtJs Mvc图片管理之二)

接着图片管理一http://www.cnblogs.com/aehyok/archive/2013/04/27/3048278.html

先来完成树目录的显示。开始前,现在解决方案中创建一个Upload目录用来存放上传的图片,为了便于测试,在Upload目录下随便添加两个目录,这里添加1和2。

好,现在创建一个名为FolderController的控制器,添加必要的引用后,先添加一个字符串常量,用来表示根目录:

string root = "../upload";

在这里使用虚拟目录是因为可以结合提交数据直接转换为实际目录。这里要注意,当放到服务器上的时候,可能目录结构会根据需要进行调整,因而好的方式是在项目的Web.Config文件中添加一个定义变量,然后从文件中提取目录,从而避免因目录改动造成的代码修改。

然后将Index方法修改为List,修改返回结果为JObject,并添加权限特性声明和一些用到的变量,代码如下:

        string root = "../upload";
        public JObject List()
        {
            bool success = false;
            string msg = "";
            JArray ja = new JArray();
            int total = 0;
            try
            {            }
            catch (Exception e)
            {
                msg = e.Message;
            }
            return Helper.MyFunction.WriteJObjectResult(success, total, msg, ja);
        }

现在要考虑怎么返回目录结构了,问题的关键是,如何为目录构建一个唯一id以标识目录。每一个目录,只有在其父目录下,其名称是唯一的,因而不能直接作为id,因而,必须加上父目录才是唯一的id。

树展开的时候,默认会以node作为关键字将树节点的id提交到服务器,因而,在服务器端,只要从node中提取数据,就是将要列的目录了,具体代码如下:

            try
            {
                string path = Request["node"] ?? "/";
                DirectoryInfo dir = new DirectoryInfo(Server.MapPath(root + path));
                foreach (var c in dir.GetDirectories())
                {
                    ja.Add(new JObject { 
                        new JProperty("id",path+c.Name +"/"),
                        new JProperty("text",c.Name),
                        new JProperty("parentId",path)
                    });
                    total++;
                }
          success = true;
            }

现在运行一下程序看看:

下面切换到PicManager.js文件,为树添加操作按钮。在创建树的配置项定义中,添加以下代码:

            tbar: [
                { iconCls: "folder-add", handler: me.onAddFolder, scope: me, tooltip: "添加目录" },
                { iconCls: "folder-delete", handler: me.onDeleteFolder, scope: me, disabled: true, tooltip: "删除目录" },
                { iconCls: "refresh", handler: me.onRefreshFolder, scope: me, tooltip: "刷新目录树" }
            ],

以上代码在树面板顶部添加了一个工具条,工具条里有添加、删除和刷新3个按钮。要正确显示按钮,还需要在app.css中添加按钮的样式代码,代码如下:

当然,别忘记将需要的图片复制到相应的目录。

现在刷新一下页面,会看到树顶部多了3个按钮。

现在为树添加2个事件,第1个是viewready事件,其作用是在树刷新后选择第1个节点。第2个是选择改变的时候,改变删除按钮的状态。在这里,不能通过id来寻找组件,因为这个组件会复用,使用的id就会有重复id。要查找也不难,直接使用down方法找按钮就行,唯一能区别删除按钮的属性有iconCls和tooltip,在这里将使用tooltip。具体代码如下:

            listeners: {
                scope: me,
                viewready: function (panel) {
                    var view = panel.getView();
                    view.getSelectionModel().select(0);
                },
                selectionchange: function (model, sels) {
                    var me = this;
                    me.tree.down("button[tooltip=删除目录]").setDisabled(sels.length == 0);

                }
            }

现在刷新页面,会看到树显示后会选择“根目录”,而删除按钮也处于开启状态了。

现在来完成添加操作,方法有2种。第1种方法是使用默认的目录名先创建一个目录,然后再让用户修改目录名。第2种方法是显示一个提示框,让用户输入目录名,然后再创建目录。简单点,这里将使用第1种方法,在PicManager.js的底部,添加一个onAddFolder方法。首先要做的是获取选择节点,以便知道是在那个目录下创建目录,代码如下:

    onAddFolder: function () {
        var tree = this.tree,
            parent = tree.getSelectionModel().getSelection()[0];
        if (!parent) {
            parent = tree.getRootNode();
        }
    },

这里添加了一个判断,以防止没有选择目录时,使用根目录作为新目录的父目录。

接着创建一个新的Folder模型并保存它,代码如下:

        var rec = new Folder({
            text: "新建文件夹",
            id: "",
            parentId: parent.data.id
        });
        rec.save({
            url: "Folder/Add",
            parentNode: parent,
            success: function (rec, opt) {
                if (opt.parentNode.isExpanded())
                    opt.parentNode.appendChild(rec);
                else
                    opt.parentNode.expand();
            },
            failure: ExtMVCOne.ModelException,
            scope: tree
        });

代码中,会发现在save方法内的配置对象中添加了一个parentNode关键字,它会指向父节点,这样的好处是,在服务器端成功添加目录后,就可直接调用parentNode通过其appendChild方法添加1个子节点。

现在,在服务端Folder控制器添加一个Add方法。在之前的文章中,可以知道,数据会以data关键字进行提交,形式是JSON数据,因而,在方法内,要先从data提取数据,然后将其转换为JArray,再在JArray中获取数据进行处理,具体代码如下:

        public JObject Add()
        {
            bool success = false;
            string msg = "";
            JArray ja = null;
            try
            {
                string data = Request["data"] ?? "";
                if (string.IsNullOrEmpty(data))
                {
                    msg = "错误的提交数据。";
                }
                else
                {
                    ja = JArray.Parse(data);
                    if (ja.Count > 0)
                    {
                        JObject jo = (JObject)ja[0];
                        string parentDir= (string)jo["parentId"];
                        string foldername= (string) jo["text"];
                        string dirPath = Server.MapPath(root + parentDir);
                        if (Directory.Exists(dirPath + foldername))
                        {
                            msg = "目录已经存在";
                        }
                        else
                        {
                            DirectoryInfo di = Directory.CreateDirectory(dirPath + foldername);
                            jo["id"] = parentDir + foldername + "/";
                            success = true;
                        }
                        
                    }
                    else
                    {
                        msg = "错误的提交数据。";
                    }
                }               
            }
            catch (Exception e)
            {
                msg = e.Message;
            }
            return Helper.MyFunction.WriteJObjectResult(success, 0, msg, ja);
        }

代码中,如果目录已经存在,就返回一个错误信息,说明目录已经存在。否则,创建新目录,并修改目录的id返回。这里一定要修改id返回,不然,新的节点的id就为空,在它下面创建目录就会出问题。

下面完成删除操作,与删除用户的代码差不多,具体代码如下:

    onDeleteFolder: function () {
        var me = this,
            tree = me.tree,
            rs = tree.getSelectionModel().getSelection();
        if (rs.length > 0) {
            rs = rs[0];
            if (rs.data.root) {
                Ext.Msg.alert("删除文件夹", "根目录不允许删除!");
                return;
            }
            var content = "确定删除目录“" + rs.data.text + "”?<br/><p style='color:red'>注意:目录下的文件及子目录都会被删除。</p>";
            Ext.Msg.confirm("删除目录", content, function (btn) {
                if (btn == "yes") {
                    var rs = this.getSelectionModel().getSelection();
                    if (rs.length > 0) {
                        rs = rs[0];
                        rs.remove();
                        this.store.sync({
                            success: function (e, opt) {
                                var me = this;
                                me.store.commitChanges();
                                me.view.select(0);
                                me.view.focus(false);
                            },
                            failure: ExtMVCOne.ModelException,
                            scope: tree
                        });
                    }
                }
            }, tree)
        }
    },

下面在Folder控制器添加一个Delete方法,代码与Add类似,不同的是在判断目录存在之后,调用Directory对象的Delete方法删除目录下的文件及其子目录,代码如下;

        public JObject Delete()
        {
            bool success = false;
            string msg = "";
            JArray ja = null;
            try
            {
                string data = Request["data"] ?? "";
                if (string.IsNullOrEmpty(data))
                {
                    msg = "错误的提交数据。";
                }
                else
                {
                    ja = JArray.Parse(data);
                    if (ja.Count > 0)
                    {
                        JObject jo = (JObject)ja[0];
                        string parentDir = (string)jo["parentId"];
                        string foldername = (string)jo["text"];
                        string dirPath = Server.MapPath(root + parentDir);
                        if (Directory.Exists(dirPath + foldername))
                        {
                            Directory.Delete(dirPath + foldername, true);
                            success = true;                            
                        }
                        else
                        {
                            msg = "目录已被删除";
                        }

                    }
                    else
                    {
                        msg = "错误的提交数据。";
                    }
                }
            }
            catch (Exception e)
            {
                msg = e.Message;
            }
            return Helper.MyFunction.WriteJObjectResult(success, 0, msg, ja);
        }

接着完成刷新操作,这个不难,重新加载Store就行了,代码如下:

    onRefreshFolder: function () {
        this.tree.store.load();
    }

现在,目录的操作就剩下编辑操作了,这个比较复杂,下文再说。

示例代码下载链接http://files.cnblogs.com/aehyok/ExtJsPic.rar

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏乐沙弥的世界

Linux/Unix shell 脚本跨服务器跨实例执行SQL

      在DB运维的过程中,难免碰到需要跨多个服务器以及多个Oracle实例查询数据库的情形。比如我们需要查看当前所有生产环境数据库上open_cursor...

17210
来自专栏小狼的世界

Curl操作Elasticsearch的常用方法

Elasticsearch对于文档操作,提供了以下几种API,本文就说明如何使用curl方式来调用这些API。

16720
来自专栏技术小黑屋

一个简易小工具,七牛Uploader for Octopress

春节假期,带着电脑回家,蹭着邻居的网,除夕晚上用ruby写了一个简单的工具。安利一下,广而告之。

11630
来自专栏熊二哥

.NET工作准备--04ASP.NET

(已过时) ASP.NET 1.开发基础 *asp.net以什么形式运行?.net宿主的概念,ISAPI的概念,ASP.NET基本运行机制; .net宿主...

25050
来自专栏云计算教程系列

如何在Ubuntu 14.04上使用Transporter将转换后的数据从MongoDB同步到Elasticsearch

Elasticsearch有助于对数据进行全文搜索,而MongoDB则擅长存储数据。使用MongoDB存储数据和使用Elasticsearch进行搜索是一种常见...

20400
来自专栏www.96php.cn

Apache多虚拟主机多版本PHP(5.3+5.6+N)共存运行配置全过程

常规的PHP配置方式有很多种,例如CGI、fast-cgi、apache module handle、cli、isapi这些。 CGI (通用网关接口 / Co...

88460
来自专栏烂笔头

Python爬虫—破解JS加密的Cookie

目录[-] 前言 在GitHub上维护了一个代理池的项目,代理来源是抓取一些免费的代理发布网站。上午有个小哥告诉我说有个代理抓取接口不能用了,返回状态521...

75770
来自专栏idba

ZanDB基于Celery定时任务的二次开发

ZanDB早期的任务需求中,大部分都是针对servant(跑在主机上的agent)做任务调度。也就是说,一期的任务系统,满足的是在特定时刻调用特定主机执行特定的...

16420
来自专栏Danny的专栏

ASP.NET实现文件的上传和下载

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

3.4K30
来自专栏Android开发指南

eclipse遇到的问题

404100

扫码关注云+社区

领取腾讯云代金券