前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ExtJs十三(ExtJs Mvc图片管理之三)

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

作者头像
aehyok
发布2018-09-11 12:33:09
3.9K0
发布2018-09-11 12:33:09
举报
文章被收录于专栏:技术博客技术博客

现在要完成目录的编辑操作。因为目录的编辑只是改变目录名称,因而使用Cellediting插件就可完成工作。要完成这个不难,首先在目录树的定义中加入以下语句隐藏列标题:

代码语言:javascript
复制
hideHeaders: true,

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

代码语言:javascript
复制
plugins: [{ ptype: "cellediting",
    listeners: {
        beforeedit: function (edit, e) {
            if (e.record.isRoot()) return false;
        }
    }
}],

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

代码语言:javascript
复制
            columns: [
                { xtype: "treecolumn", dataIndex: "text", flex: 1,
                    field: { allowBlank: false, selectOnFocus: true }
                }
            ],

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

代码语言:javascript
复制
viewConfig: {
    toggleOnDblClick: false
},

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

代码语言:javascript
复制
                    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方法类似,因而可以直接复制粘贴一下,修改方法名和具体处理过程就行了,代码如下:

代码语言:javascript
复制
public JObject 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;
            }
            return Helper.MyFunction.WriteJObjectResult(success, 0, msg, ja);
        }

至此,目录的全部操作就完成了。至此,目录的全部操作就完成了。

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

代码语言:javascript
复制
                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的差不多,因而可以直接复制过来修改。修改后的代码如下:

代码语言:javascript
复制
        string root = "../upload";
        public JObject 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 = new DirectoryInfo(Server.MapPath(root + path));
                total = dir.GetFiles().Count();
                foreach (var c in dir.GetFiles().OrderByDescending(m => m.LastWriteTime).Skip(start).Take(50))
                {
                    ja.Add(new JObject { 
                        new JProperty("path",path),
                        new JProperty("filename",c.Name),
                        new JProperty("modify",c.LastWriteTime.ToString("yyyy-MM-dd hh:mm")),
                        new JProperty("size",c.Length)
                    });
                }
                success = true;

            }
            catch (Exception e)
            {
                msg = e.Message;
            }
            return Helper.MyFunction.WriteJObjectResult(success, total, msg, ja);
        }

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

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

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

代码语言:javascript
复制
  <configSections>
    <section name="resizer" type="ImageResizer.ResizerSection" requirePermission="false" />
  </configSections>

然后添加以下配置:

代码语言:javascript
复制
  <resizer>
    <plugins>
      <!-- So all the sample projects can share the same image folder-->
      <add name="VirtualFolder" virtualPath="~/Thumbnail/" physicalPath=".\Upload" />
      <!-- So Mvc doesn't prevent the image resizer from working -->
      <add name="MvcRoutingShim" />
      <add name="DiskCache" />
    </plugins>
  </resizer>

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

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

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

代码语言:javascript
复制
  <httpModules>
    <add name="ImageResizingModule" type="ImageResizer.InterceptModule" />
  </httpModules>

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

代码语言:javascript
复制
<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的定义来将图片转换为缩略图所需的宽度和高度,然后返回给客户端,非常的方便。

下面可以运行查看

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

代码语言:javascript
复制
.imageList{float:left;display:block;width: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;
}

下面再刷新一下看看

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013-04-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档