当前位置: 代码迷 >> Web前端 >> CMS之图片治理(1)
  详细解决方案

CMS之图片治理(1)

热度:281   发布时间:2012-10-20 14:12:47.0
CMS之图片管理(1)

图片管理要在两个地方使用:一是标签页内的图片管理,一是文章内容编辑时嵌套到插入图片的窗口内。因而,将图片管理做成一个扩展比较方便。当然,做成MVC模式也行,不争论,不讨论。

要记住,扩展要写在Scripts\ExtJS\Ux目录下,因为在路径的设置中,扩展目录是指向这里的。在该目录下创建一个名为PicManager.js的脚本文件。

图片管理的主要界面分两部分,左边以树的形式列出文件目录,要实现目录的添加、删除和编辑功能,右边则以预览形式显示目录中的文件,主要功能是上传文件和删除文件。

上传文件将使用Swfupload,它可一次上传多个文件,到http://code.google.com/p/swfupload/可下载到最新版本的文件,当前示例使用的是2.5.0 beta版本。先下载SWFUpload_v250_beta_3_samples.zip这个文件,解压后,把demos目录下的swfupload目录复制到解决方案的Scripts目录下。然后下载swfupload.swf.v2.5.0.beta3.2.zip文件,把该文件里的文件覆盖swfupload目录下的文件。

好,现在可以开始编写图片管理的脚本文件了,图片管理的界面将从容器扩展,使用边框布局,代码如下:

Ext.define('Ext.ux.PicManager',{

    extend: 'Ext.container.Container',

    alias: 'widget.picmanager',

    layout: "border",

 

    initComponent: function () {

        var me = this;

        me.callParent(arguments);

    }

});

 

现在先来完成左边的目录树。使用树,必然用到TreeStore,因而要从这里入手。而TreeStore可定义模型,也可不定义模型,这个视情况而定。目前的情况是,目录的添加、编辑和删除操作,都需要给出父目录和目录名称,目录名称可使用字段text,父目录则是一个附加字段。目录的操作比较简单,因而直接在模型内完成就行了,因而定义模型是比较好的方法。模型的定义可以独立成一个文件,也可以在initComponet方法内定义。如果在独立的文件定义,就要在扩展中添加requires配置项引用模型。这里将在initComponet方法内定义,代码如下:

Ext.define("Folder",{

    extend: "Ext.data.Model",

    fields: ["text", "id","parentId"],

    validations: [{

        type: 'presence',

        field: 'text'

    }],

    proxy: {

        type: 'ajax',

        api: {

            read: 'Folder/List',

            create: 'Folder/Add',

            destroy: 'Folder/Delete',

            update: 'Folder/Edit'

        },

        reader: {

            messageProperty: "Msg",

            type: 'json',

            root: "data"

        },

        writer: {

            type: "json",

            encode: true,

            root: "data",

            allowSingle: false

        },

        listeners:{

            exception :SimpleCMS.ProxyException

        }

    }

});

 

定义中,parentId用来记录父目录。添加一个验证项,目录名称不能为空。在代理定义中,reader和writer的定义可标准化数据的输入输出,这个与用户中的定义是一样的。代理的API则定义了操作的提交路径。

接下来定义TreeStore,代码如下:

        me.treestore = Ext.create("Ext.data.TreeStore", {

           root: { id: "/", text: "根目录",expanded: true },

            model: "Folder"

        });

 

TreeStore的定义,除了模型,很重要的一个定义就是根节点了。这里根节点的id使用“/”,是为了方便后台将虚拟路径转换为实际路径。

接着定义树面板,代码如下:

me.tree= Ext.widget("treepanel", {

    title: "文件目录", region: "west", collapsible: true, rootVisible:true,

    width: 250, minWidth: 100, maxWidth: 500,split: true, store: me.treestore   

});

 

因为使用边框布局,因而要混入边框布局的配置项。这里还设置了显示根目录,这是因为系统将允许在根目录上传文件。

现在来完成右边的文件预览。还是先从模型开始,代码如下:

Ext.define('File',{

     extend: 'Ext.data.Model',

     fields: [

        'filename','path',

        "modify",

        { name: "size", type:"int"}

       

     ]

 });

 

这里的字段,除了文件名、路径是必须的,其它的可根据自己的显示内容定义。在这里将显示最后编辑时间、文件大小。

接着是定义Store,代码如下:

me.filestore= Ext.create("Ext.data.Store", {

    batchActions: false,

    remoteFilter: false,

    remoteSort: false,

    pageSize: 50,

    model: "File",

    proxy: {

        type: "ajax",

        api: {

            read: 'File/List',

            destroy: 'File/Delete'

        },

        reader: {

            type: 'json',

            root: "data"

        },

        writer: {

            type: "json",

            encode: true,

            root: "data",

            allowSingle: false

        },

        listeners:{

            exception :SimpleCMS.ProxyException

        }

    }

});

 

这里的API没有create和update配置项是因为,文件是上传的,不能通过该方式提交,而文件一般也不进行更新,而是先删除后再上传。

接着是用数据视图来显示文件,代码如下:

me.dataview= Ext.widget("dataview", {

    store: me.filestore, autoScroll: true,

    multiSelect: true, selectedItemCls:"selected", itemSelector: 'div.imageList',

    overItemCls: "overitem",trackOver: true,

    tpl: [

        '<tpl for=".">',

            '<div class="imageList">',

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

                '<p class="ellipsis">{filename}</p>',

            '</div>',

        '</tpl>',

        '<div class="x-clear"></div>',

         {

            filesize: function (size) {

                if (size < 1024) {

                     return v + " 字节";

                } else if (size < 1048576) {

                     return (Math.round(((size * 10)/ 1024)) / 10) + " KB";

                } else {

                     return (Math.round(((size * 10)/ 1048576)) / 10) + " MB";

                }

            }

         }

     ]

});

 

定义数据视图的关键就是模板的定义,这个在书中有详细说明和示例,这里就不详细说了。在这里在模板添加了一个filesize方法,用来转换文件大小的显示格式。

因为视图不是面板,没有工具栏组件,因而要在其外面套一个面板用来放置工具栏,所以在视图的定义中没有边框布局的配置项。

下面来完成整个界面框架,代码如下:

me.items= [

    me.tree,

    {title:"图片文件",region: "center",layout:'fit',items:[me.dataview]}

];

 

现在可以调试一下界面,看看怎么样了。先切换到主面板(mainpanel.js)的视图定义,为图片管理加回布局,布局类型为Fit。然后切换到主面板的控制器,在图片管理的activate方法内,删除console语句,添加以下代码:

varview = Ext.create('Ext.ux.PicManager', {});

panel.add(view);

 

这里一定要注意,create方法的第一参数必须为字符串,这样,Ext才会去自动加载类文件。也不能使用widget方法去创建,因为类还没注册,Ext不知道别名为picmanager指向的是那个类,也就不会去自动加载了。如果不使用这样的方式,可在控制器中加入requires配置项,指定要加载该类,不过这与初衷相违了。

为了调试方便,可在主面板视图定义中加入配置项activeTab,用来指定初始激活显示那个标签页,这样就不用每次调试都要单击一次标签了。图片管理是第二个标签页,因而设置当前索引为1。

在浏览器中打开图片管理,将看到如图31所示的图片。基本框架就搭建起来了,余下的就是实现功能了。



  相关解决方案