CMS:文章管理之视图(2)

上一篇已经完成了分类树的显示,现在开始逐步完成分类的添加、删除和编辑操作。
首先要做的是在树面板上添加一个工具栏,放置添加、删除和编辑按钮。切换到文章管理视图的脚本文件view.js,在树的定义内,添加以下代码添加工具栏和按钮:
tbar: [
    { iconCls: "folder-add", scope:me, tooltip: '增加文章类别',id:"CategoryButtonAdd"},
    { iconCls: "folder-edit", scope:me, tooltip: '编辑文章类别',id:"CategoryButtonEdit",disabled:true},
    { iconCls: "folder-delete",scope: me, tooltip: '删除文章类别',id:"CategoryButtonDelete",disabled:true},
    { iconCls: "refresh", scope: me,qtip: '刷新',id:"CategoryButtonRefresh" }
]
 
以上代码基本是复制来复制去的了,没什么特别。样式里还没定义编辑按钮的样式,在app.css里加上就行了。
现在切换到文章管理控制器的脚本Content.js,通过它们的id,添加4个按钮的引用,代码如下:
{ ref:"CategoryAdd", selector: "#CategoryButtonAdd" },
{ ref:"CategoryEdit", selector: "#CategoryButtonEdit" },
{ ref:"CategoryDelete", selector: "#CategoryButtonDelete" },
{ ref: "CategoryRefresh", selector:"#CategoryButtonRefresh" }
 
然后和用户管理控制器一样,为4个按钮绑定单击事件,代码如下:
me.getCategoryAdd().on("click",me.onCategoryAdd, me);
me.getCategoryEdit().on("click",me.onCategoryEdit, me);
me.getCategoryDelete().on("click",me.onCategoryDelete, me);
me.getCategoryRefresh().on("click",me.onCategoryRefresh, me);
 
现在,先完成比较简单的刷新操作,因为要找到文章管理的视图,因而修改一下使用widget方法创建视图时的代码,让它保存到控制器的属性中,修改代码如下:
me.view= Ext.widget("contentview");
panel.add(me.view);
 
这样修改后,就不需要通过引用去找视图了。现在就可轻松完成树的刷新操作了,代码如下:
onCategoryRefresh:function () {
    this.view.tree.store.load();
},
 
添加操作将通过一个带表单的弹出窗口实现,现在来创建这个窗口。在Scripts\app\view\Content目录下创建一个名称为CategoryEdit.js的脚本文件。因为是弹出窗口,因而需要从窗口继承,代码如下:
Ext.define("SimpleCMS.view.Content.CategoryEdit",{
    extend: "Ext.window.Window",
    hideMode: 'offsets',
    closeAction: 'hide',
    closable: true,
    resizable: true,
    layout: "fit",
    title: '文章分类',
    width: 800,
    height: 600,
    modal: true,
singleton: true,
 
    initComponent: function () {
        var me = this;
        me.callParent(arguments);
    }
 
})
 
代码表明窗口可以关闭,可以调整大小,布局将采用FitLayout,默认宽度为800,高度为600,窗口为模态窗口。配置项closeAction表明窗口关闭后,只是隐藏起来,并不是销毁,而且隐藏方式是通过偏移方式隐藏。
特别要注意,在这里把窗口设置成了单例模式(配置项singleton为true),目的是为了避免在控制器中先判断窗口是否已经创建,如果还没有,还要重新调用create方法创建一次。
如果想看一下效果,可切换到文章管理控制器,在视图内添加“Content.CategoryEdit”引用该视图。然后在onCategoryAdd方法内添加以下代码:
onCategoryAdd:function () {
    var me = this
        win =SimpleCMS.view.Content.CategoryEdit;
    win.show();
},
 
好了,现在刷新一下浏览器,然后单击添加类别按钮,将看到如图49所示的效果,一切正常。
图50 分类编辑窗口
现 在,要做的就是为窗口添加表单了,根据表格T_Category,需要编辑的字段包括父类、标题、题图、分类说明和排序序数。标题将采用 Textfield进行输入,题图则要通过显示一个弹出窗口,从图片管理这个扩展中选择后插入,排序序数则可选择使用Number字段输入,分类说明则用 Textarea字段,父类不用说是采用Combobox。
因为要用到一个图片插入对话框,因而先来完成这个,这个不难,在 Scripts/Extjs/ux目录下先创建一个Dialog的目录,该目录的作用是用来放置一些对话框扩展。然后在该目录下创建一个 PicSelected.js的文件,然后可以复制一下分类编辑窗口的代码过去,修改一下类名和配置项就可以了,代码如下:
Ext.define("Ext.ux.Dialog.PicSelected",{
    extend: "Ext.window.Window",
    requires: ["Ext.ux.PicManager"],
    singleton: true,
    hideMode: 'offsets',
    closeAction: 'hide',
    closable: true,
    layout: "fit",
    imagePath: "",
    resizable: true,
    title: '插入图片',
    width: 1000,
    height: 600,
    modal: true,
    initComponent: function () {
        var me = this;
 
        me.callParent(arguments);
    }
 
})
 
熟 记类名规则对怎么定义类名就没什么难度。在这里添加了一个requires的配置项,表明该对话框要用到扩展PicManager。因为后台的图片访问路 径和前台的访问路径可能有差,因而这里特意添加了一个imagePath属性,用来在插入时更改路径。其它的配置项与分类编辑窗口基本无差。
对话框的主要作用就是显示PicManager让用户选择图片,然后单击插入按钮插入图片路径,功能比较简单,因而在initComponent的代码比较简单,具体代码如下:
me.picmanager= Ext.create("Ext.ux.PicManager", { title: "" });
me.items= [me.picmanager];
me.dockedItems= [{
    xtype: 'toolbar', dock: 'bottom', ui:'footer', layout: { pack: "center" },
    items: [
            { text: "插入", width: 80, handler:me.onInsert, scope: me }
    ]
}];
 
现在,要完成插入操作。要插入图片,首先要从PicManager中获取到选择的图片,这个不难。然后,要获取插入图片的控件,这个就需要在显示对话框的时候指定了,可通过一个名为ed的属性来实现。思路明确后,就可编写代码了,具体代码如下:
onInsert:function () {
    var me = this, rs = me.picmanager.dataview.getSelectionModel().getSelection();
    if (rs.length > 0) {
        if (me.ed.isFormField) {
            me.ed.setValue(Ext.String.format("{0}{1}{2}",me.imagePath, rs[0].data.path, rs[0].data.filename));
        } else {
        }
    }
    me.close();
}
 
代码先从扩展中获取数据视图的选中的记录,如果有存在选择记录,则判断ed指向的控件是否一个表单字段,如果是,就可以用setValue方法设置它的值了。通过Ext中字符串的format方法可以将访问路径、图片路径和文件名组合成字符串返回给控件。
 
现在返回分类编辑窗口,完成表单,先写好表单的定义,如果已经做过项目,有写好的表单,复制粘贴就行了,代码如下:
me.form= Ext.create(Ext.form.Panel, {
    border: false, bodyPadding: 5,
    bodyStyle: "background:#DFE9F6",
    trackResetOnLoad: true,
    fieldDefaults: {
        labelWidth: 80, labelSeparator: ":", anchor: "0"
    },
});
 
表 单的显示方式完全是个人喜欢,根据自己熟悉和喜好进行定义就好了。这里把表单的表框去了,然后将放置子组件部分向内压缩了5px,以避免文字和窗口的内边 框贴在一起。背景颜色如果不设置就是白色的底色,笔者一向不太喜欢这样白色的背景。尤其要注意trackResetOnLoad这个配置项,如果为 true,当为表单设置了初始数据后,重置操作后会恢复到初始数据,而不是完全空白的状态。配置项fieldDefaults就是默认的字段定义了,适用 于所有字段。
接着就是在表单items配置项里添加字段了,首先是一个隐藏字段,用来记录编辑时的记录的id,代码如下:
{xtype:"hidden",name:"CategoryId"},
接着是标题,代码如下:
{ xtype: "textfield", fieldLabel: "标题", name: "Title",allowBlank: false},
题图复杂点,需要用一个字段容器来放置一个文本字段和选择按钮,代码如下:
{
    xtype: "fieldcontainer", layout:"hbox", fieldLabel: "题图", defaults: { hideLabel: true },
    items: [
            { xtype: 'textfield', flex: 1, name:"Image" },
            { xtype: "button", width:80, text: "选择",
               handler: function () {
                    var img = this.up("form").getForm().findField("Image");
                    Ext.ux.Dialog.PicSelected.ed = img;
                    Ext.ux.Dialog.PicSelected.show();
               }
            }
     ]
}
 
从代码可以看到单击选择按钮后,会先从表单中找到Image字段,然后把图片选择对话框的ed属性指向该组件,再显示图片选择对话框就可以了。
因为这里要用到图片选择对话框,因而需要在窗口定义中加入requires配置项来引用该对话框。
如果想预览题图,可以加入一个Image组件,代码如下:
{
     xtype: 'fieldset', title: "题图预览", height: 150, items: [
            { xtype: "image", id:" CategoryPreviewImage" }
     ]
}
这还要修改一下Image字段,监听它的chage事件,当字段改变时,改变图片的src,代码如下:
{xtype: 'textfield', flex: 1, name: "Image",
    listeners: {
        scope: me,
        change: function (filed, newValue,oldValue) {
           Ext.getCmp("CategoryPreviewImage").setSrc(newValue);
        }
    }
},
 
接着是父类选择,代码如下:
{
     xtype: "combobox", fieldLabel:"父类", name:"ParentId", allowBlank: false,
     editable: true, shadow: false, mode:'local', triggerAction: 'all', store: "categoriesCombo",
     rootVisible: true, displayField:"text", valueField: "id", flex: 1,
     listConfig: {
            displayField: "listText"
     }
},
 
这 里要特别说明一下,笔者自己都忘记了。因为分类编辑窗口是单例模式的,会直接创建实例,而且是先于控制器创建,因而这里的Combobox要用到 CategoriesCombo,必须在requires添加引用,而且要将CategoriesCombo也设置为单例模式,且添加配置项 storeId,为它定义一个标识,再在Combobox里引用。在文章管理控制器里,还要把配置项stores中对该Store的引用删除。
在Combobox中,列表中的数据不是非要使用displayField设置的字段来显示的,可通过listConfig配置项,重新设置显示字段。在这里,设置了显示字段为listText,笔者这样做的目的是为了使列表显示得像一颗树。
余下是排序序数和分类说明,这个不难,代码如下:
{
    xtype: 'numberfield', fieldLabel: "排序序数", name: "SortOrder",allowBlank: false
},
{
    xtype:'textareafield',fieldLabel: "说明",name:"Content",labelAlign:"top",height:250
}
 
接着在表单底部放置保存和重置两个按钮,代码如下:
dockedItems:[{
    xtype: 'toolbar', dock: 'bottom', ui:'footer', layout: { pack: "center" },
    items: [
         {text: "保存", width:80, disabled: true, formBind: true, handler: me.onSave, scope: me },
         {text: "重置", width:80, handler: me.onReset, scope: me }
    ]
}]
 
保存按钮默认状态禁用的,设置了formBind为true,也就是说只有所有字段输入符合要求的时候才可以开启保存按钮,这样比较方便。
现在把表单放到窗口的items里,代码如下:
me.items = [me.form];
 
现在可以测试一下窗口了,刷新一下浏览器,然后单击添加分类按钮,可看到如图50的效果。底部按钮太靠近窗口底部了,需要调整一下,这个可通过设置窗口bodyPadding来实现,在单例模式的配置项下添加以下代码:
bodyPadding:"00 10 0",
图50 完成后的分类编辑窗口

这样,窗口底部就会向内缩进10px,按钮也就不再靠近窗口底部了,刷新一下浏览器,会看到如图51的效果。
图51 调整按钮位置后的分类编辑窗口
测试一下选择图片,在弹出的图片对话框中,选择8.png,然后单击插入按钮,会看到题图的值为“/8.PNG”,但是预览图片没效果,这是因为图片路径不对。因为现在没有前台,所以直接使用后台的路径作为图片路径就好了,在选择按钮的单击事件中,添加以下代码:
Ext.ux.Dialog.PicSelected.imagePath= "upload";
 
刷新一下浏览器,再选择图片8.PNG,会看到值已经变为“upload/8.PNG”,如图52,预览图片也显示出来了。
 
图52 调整图片路径后的预览图片显示
下面要完善父类的选择,这个下文再说。

你可能感兴趣的:(JavaScript,cms,mvc,ExtJs,ASP/ASP.NET)