• CMS之图片管理(2)


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

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

    stringroot = "../upload";

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

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

    [AjaxAuthorize(Roles= "普通用户,系统管理员")]

    publicJObject List()

    {

        bool success = false;

        string msg = "";

        JArray ja = new JArray();

        int total = 0;

        try

        {

        }

        catch(Exception e)

        {

            msg = e.Message;

        }

        returnHelper.MyFunction.WriteJObjectResult(success, total, msg, ja);

    }

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

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

    stringpath = Request["node"] ?? "/";

    DirectoryInfodir = new DirectoryInfo(Server.MapPath(root + path));

    foreach(var c in dir.GetDirectories())

    {

       ja.Add(new JObject {

            newJProperty("id",path+c.Name +"/"),

            new JProperty("text",c.Name),

            newJProperty("parentId",path)

        });

        total++;

    }

    success = true;

    现在生成应用,并在浏览器查看,可看到如图32所示,文件目录已经列出来了。


    图32 树目录

    下面切换到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中添加按钮的样式代码,代码如下:

    .folder-add{

         background:url("../images/folder_add.png")!important;

    }

    .folder-delete{

         background:url("../images/folder_delete.png")!important;

    }

    .refresh{

    background:url("../../../extjs/resources/themes/images/default/grid/refresh.gif")!important;

    }

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

    现在刷新一下页面,会看到树顶部多了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模型并保存它,代码如下:

    varrec=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: SimpleCMS.ModelException,

         scope:tree

    });                

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

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

    [AjaxAuthorize(Roles= "普通用户,系统管理员")]

    publicJObject 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) {

                             varme=this;

                                me.store.commitChanges();

                                me.view.select(0);

                                me.view.focus(false);

                            },

                            failure:SimpleCMS.ModelException,

                            scope: tree

                        });

                    }

                }

            }, tree)

        }

    },

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

    [AjaxAuthorize(Roles= "普通用户,系统管理员")]

    publicJObject 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;

        }

        returnHelper.MyFunction.WriteJObjectResult(success, 0, msg, ja);

    }

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

    onRefreshFolder:function () {

        this.tree.store.load();

    }

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

    BTW:代码我已该放到新浪微盘了

    源代码:http://vdisk.weibo.com/s/g7Z33

  • 相关阅读:
    分页封装实用工具类及其使用方法
    Oracle
    [置顶] Android高德地图显示气泡框
    设计模式 笔记 观察者模式
    数据质量,中国希望
    谁更胜一筹:技术解析 Google App Engine 和 Amazon EC2
    GZIP Http Servlet Response
    谁更胜一筹:技术解析 Google App Engine 和 Amazon EC2
    腾讯对外发布微博开放平台 API
    GZIP Http Servlet Response
  • 原文地址:https://www.cnblogs.com/muyuge/p/6333743.html
Copyright © 2020-2023  润新知