zoukankan      html  css  js  c++  java
  • CMS之图片管理(3)

    现在要完成目录的编辑操作。因为目录的编辑只是改变目录名称,因而使用Cellediting插件就可完成工作。

    根据书11.3.2节的示例,要完成这个不难,首先在目录树的定义中加入以下语句隐藏列标题:

    hideHeaders:true,

    接着添加plugins配置项来配置CellEditing插件。因为根目录是不运行编辑的,因而需要监听beforeedit事件,如果当前选择节点是根目录就返回false,不允许编辑,代码如下:

    plugins:[{ ptype: "cellediting",

        listeners: {

            beforeedit: function (edit, e) {

                if (e.record.isRoot()) returnfalse;

            }

        }

    }],

    继续定义columns配置项,为目录添加编辑控件,代码如下:

    columns:[

         { xtype: "treecolumn", dataIndex:"text", flex: 1,

            field: { allowBlank: false, selectOnFocus: true }

         }

    ],

    最后定义viewConfig配置项,取消树节点默认的双击操作,代码如下:

    viewConfig:{

         toggleOnDblClick:false

    },

    好了,现在要考虑的是修改后的提交问题了。Cellediting插件在编辑完成后,会触发edit事件,因而在这时候提交数据是最合适的,代码如下:

    edit:function(edit,e){

         e.record.save({

                success:function(rec,opt){

                        opt.records[0].setId(opt.records[0].data.parentId+opt.records[0].data.text+"/");

                        opt.records[0].commit();

                },

                failure:function(e,op){

                        op.records[0].reject();                                     

                        Ext.Msg.alert("发生错误",op.error);

                }

         });

    }

    在edit事件中,它的第2个参数会返回修改后的记录,因而直接调用模型的save方法就可提交数据了。如果提交成功后需要根据返回数据修改记录的id,并调用commit方法确认修改。如果修改失败,就要调用reject方法取消修改。

    现在切换回Folder控制器,完成编辑操作的服务器端代码,基本过程与Add方法类似,因而可以直接复制粘贴一下,修改方法名和具体处理过程就行了,代码如下:

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

    publicJObject Edit()

    {

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

                    string oldPath = Server.MapPath(root +(string)jo["id"]);

                    if (Directory.Exists(oldPath))

                    {

                        if(Directory.Exists(dirPath + foldername))

                        {

                            msg = "目录已经存在";

                        }

                        else

                        {

                            Directory.Move(oldPath,dirPath + foldername);

                            jo["id"] =parentDir + foldername + "/";

                            success = true;

                        }

                    }

                    else

                    {

                        msg = "要修改的目录不存在";

                    }

     

                }

                else

                {

                    msg = "错误的提交数据。";

                }

            }

        }

        catch (Exception e)

        {

            msg = e.Message;

        }

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

    }

    至此,目录的全部操作就完成了。如果想功能更完善,最好加入目录拖拽功能,这个笔者就不做了,有兴趣的自己可根据书的内容去完成。

    现在要完成的是单击树节点,在图片列表中显示该目录下的图片文件。要做的就是监听树的selectionchange事件,这个可参考书中的11.3.4节的示例,具体代码如下:

    selectionchange:function (model, sels) {

        var me = this;

        if (sels.length > 0) {

            var rs = sels[0],

                        store = me.filestore;

            store.proxy.extraParams.path =rs.data.id;

            store.loadPage(1);

        }

        me.tree.down("button[tooltip=删除目录]").setDisabled(sels.length ==0);

     

    }

    现在来完成返回文件数据的控制,创建一个名称为FileController的控制器。加入必要的引用后,和Folder控制器一样,加入一个root的字符串变量来指定根目录。因为File控制器的List方法与Folder的差不多,因而可以直接复制过来修改。修改后的代码如下:

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

    publicJObject List()

    {

        bool success = false;

        string msg = "";

        JArray ja = new JArray();

        int total = 0;

        try

        {

            int start = 0;

           int.TryParse(Request["start"], out start);

            string path = Request["path"]?? "/";

            DirectoryInfo dir = newDirectoryInfo(Server.MapPath(root + path));

            total = dir.GetFiles().Count();

            foreach (var c indir.GetFiles().OrderByDescending(m => m.LastWriteTime).Skip(start).Take(50))

            {

                ja.Add(new JObject {

                    newJProperty("path",path),

                    newJProperty("filename",c.Name),

                    newJProperty("modify",c.LastWriteTime.ToString("yyyy-MM-ddhh:mm")),

                    newJProperty("size",c.Length)

                });

            }

            success = true;

     

        }

        catch (Exception e)

        {

            msg = e.Message;

        }

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

    }

    从代码中可以看到,使用LINQ真的太方便了,分页就是小菜一碟。目前暂时只设置了使用最后修改时间排序,等下再研究怎么修改排序。

    现在还不能进行测试,因为要解决图片的缩略图显示问题。本示例,不用为每一个上传的图片生成缩略图,只要直接上传就好了,因为NuGet上有一个名称为ImageResizer.MVC的包,非常好用,它会自动根据请求生成缩略图。在主菜单选择工具>库程序包管理>管理解决方案的NuGet程序包打开管理NuGet程序包窗口,然后搜索ImageResizer,找到ImageResizer.MVC后,选择安装。

    安装后,还要在Web.convfig文件进行配置。打开WebConfig文件,首先在configuration段内添加以下代码为ImageResize添加一个配置段:

    <configSections>

         <section name="resizer"type="ImageResizer.ResizerSection"requirePermission="false" />

    </configSections>

    然后添加以下配置:

      <resizer>

        <plugins>

          <!-- So all the sample projects canshare the same image folder-->

          <add name="VirtualFolder"virtualPath="~/Thumbnail/" physicalPath=".\Upload" />

          <!-- So Mvc doesn't prevent the imageresizer from working -->

          <add name="MvcRoutingShim"/>

          <add name="DiskCache" />

        </plugins>

     </resizer>

    配置中,VirtualFolder的作用是将虚拟目录和物理目录关联起来,其中的virtualPath就是要定义的虚拟目录,在这里是“~/Thumbnail/”,而对应的物理目录physicalPath就是“.\Upload”。

    配置DiskCache的作用是开启磁盘缓存,它会把生成的缩略图缓存在磁盘上,这样就不用访问相同的缩略图时,每次都要去生成了。

    接着在system.web段内添加以下配置:

    <httpModules>

      <add name="ImageResizingModule"type="ImageResizer.InterceptModule" />

    </httpModules>

    那么它是如何工作的呢?切换回PicManager.js文件,找到DataView定义的模板,会看到图片的显示是这样的:

    <img width="160"height="160"src="../Thumbnail{path}{filename}?width=160&height=160"data-qtip="文件名:{filename}<br/>修改日期:{modify}<br>大小:{size:this.filesize}"/><br/>

    在src定义的路径中,会看到文件名后多了参数width和height的定义,而ImageSize在路由中检查到访问的虚拟路径时,就会根据width和height的定义来将图片转换为缩略图所需的宽度和高度,然后返回给客户端,非常的方便。

    把一些图片复制到根目录,然后重新生成一下解决方案,在浏览器中打开图片管理,将看到如图33的效果。


    Oh,NO!DataView居然显示出错了。用Firebug检查每个视图条目,居然宽度是占满一行的,仔细看了一下样式定义,居然发现条目上定义的样式没有,很显示是忘记在app.css内定义条目的样式了。于是把以下样式定义追加到app.css文件内:

    .imageList{float:left;display:block;180px;height:200px;padding:10px;}

    .selected{background-color:#D3E1F1;}

    .overitem{background-color:#E7E7E7;}

    .imageListp{

         text-align:center;

         overflow:hidden;

         line-height:22px;

    }

    .ellipsis{-o-text-overflow:ellipsis;text-overflow:ellipsis;-moz-binding:url('ellipsis.xml#ellipsis');white-space:nowrap;overflow:hidden;}

    .x-view-selector{

        position: absolute;

        border: 1px dotted #3399BB;

    }

    刷新一下页面,如图34,视图显示正常了。

     

    好了,今天就到这了。


    源代码地址:http://vdisk.weibo.com/s/gFNr7

  • 相关阅读:
    第五章 条件语句
    第四章 javaScript运算符
    第三章 javaScript数据类型
    看电影学英语十
    英语口语会话十
    看电影学英语九
    英语口语会话九
    英语口语会话八
    看电影学英语八
    Linux command line and shell scripting buble
  • 原文地址:https://www.cnblogs.com/hainange/p/6334234.html
Copyright © 2011-2022 走看看