CMS:文章管理之视图(1)
文章管理的视图与文件管理区别不大,都是分左右两部分。文章管理的左边是树状的分类列表,右边以Grid形式显示的文章列表。基本上重复劳动比较多,使用Sencha Architect这个可视化工具来做这方面的设计,是不错的选择,如果公司收益好,强烈建议使用,一个开发包的价格是399美金,大约2800人民币,还是很划得来的,起码比请多个程序员划得来。
废话又有点多了,转回正题,在Scripts\app\view目录下,创建一个Content目录,用来存放文章管理需要用到的视图,主要的视图包括文章管理的主视图、分类编辑窗口和文章编辑窗口。
接着,在Content目录下创建一个名称为View.js的文件,用来定义主视图,基本结构代码如下:
Ext.define('SimpleCMS.view.Content.View',{
extend: 'Ext.container.Container',
alias: 'widget.contentview',
layout:"border",
initComponent: function () {
var me = this;
me.callParent(arguments);
}
});
接下来就是一步步添加组件了,先完成树的定义,代码如下:
me.tree= Ext.widget("treepanel", {
title: "文章类别", region: "west", collapsible: true, rootVisible:true, store: "CategoriesTree",
width: 200, minWidth: 100, split: true
});
接着是Grid,代码如下:
me.grid= Ext.widget("grid", {
title: "文章列表", region: "center",
store: "Contents",
selType: "checkboxmodel",
selModel: { checkOnly: false, mode:"MULTI" },
columns: [
{ text: '编号', dataIndex: 'ContentId', width: 80},
{ text: '标题', dataIndex: 'Title', flex: 1 },
{xtype: "datecolumn", text: '创建时间', dataIndex: 'Created', format: "Y-m-d H:i:s", width: 150},
{ text: '排序序数', dataIndex: 'SortOrder', width: 80},
{ text: '点击量', dataIndex: 'Hits', width: 80 },
{ text: '标签', dataIndex: 'Tags',width:150 }
]
});
Grid使用了复选框作为选择行的方式,也是一向习惯了。其它方面,应该问题不大。
最后是将树和Grid放到容器里,代码如下:
me.items = [me.tree, me.grid];
现在,可以测试一下效果了,不过,这还有修改控制器,切换到文章管理的控制器,在init方法内创建视图,并添加到面板里,这个应该很熟悉了,在用户管理和图片管理已经做过了。忘记了就直接复制过来修改一下创建的视图就行了,具体代码如下:
var me= this,
panel = me.getContentPanel(),
view = Ext.widget("contentview");
panel.add(view);
代码的panel用到了getContentPanel方法,返回文章管理的面板,因而要添加引用,代码如下:
refs: [
{ ref: "ContentPanel", selector:"#contentPanel" },
],
当然了,不要忘记在views配置项内添加视图了,代码如下:
views:[
'Content.View'
],
在浏览器打开后,屏幕居然什么都没显示出来,而在Firebug居然显示两个“Layout run failed”错误,说明布局有问题。这个在之前也碰到过了,就是主面板定义中,没定义文章管理面板的布局,现在切换到主面板的视图,在文章管理的面板定义上加回布局定义,布局使用Fitlayout。
刷新一下浏览器,就可看到如图40的效果了。
现在来完成分类树的功能,先完成树的显示。在完成前,先要用实体框架,将数据库中的表转换为对象。在解决方案内添加一个新项,然后如图41所示,在添加新项窗口中,先选择数据模版,然后在中间选择ADO.NET实体数据模型,将名称修改为SimpleCMS.edmx后,单击添加按钮。
选择从数据库生成,然后单击下一步。
在 选择您的数据连接窗口中,可以单击新建连接按钮新建一个连接。在不过,默认的ApplicationServices连接是在配置文件中定义好的连接,可以直接使用,就不必再创建新的了。选上“是,在连接字符串中包括敏感数据”后,单击下一步按钮。当然,如果不喜欢在Web.Config文件包含用户名和密码这些敏感数据,可以另行处理。
在 选择数据库对象窗口中,展开树中的表,然后如图那样选择以“T_”开头的4个表格,然后单击完成按钮结束向导。
等待生成完成后,会在解决方案中看到如图45所示的数据结构图。
看到图,一定会疑惑,为什么刚才选择了4个表格,怎么在这里只看到3个对象?这是因为连接表T_Content和T_Tag的关联表在对象中只是一种多对多关系,隐含在对象中了,因而,不需要像数据库那样,显式的表示成一个对象。
这里还要为T_Category添加一个关联,让父节点可以找到它的子节点。在T_Category 的图中单击鼠标右键,在右键菜单中选择添加>关联,在如图46所示的添加关联对话框中,修改右边的实体为T_Category,接着修改左边的多重性为“0...1(零或一个)”。接着修改左边的导航属性为Childs,这样,就可通过childs属性访问子节点了。然后将右边的导航属性修改为Parent,这样,通过Parent属性就可访问到父节点了。把复选框的勾去掉后,单击确定按钮完成添加关联操作。
接着在右边的属性列表中,编辑引用约束,在如图47的引用约束对话框中,选择主体为T_Category,然后在表格中将CategoryId的依赖属性设置为ParentId。
保存一下解决方案,然后新建一个服务器端的控制器Category,添加必要的引用后,添加一个只读的私有变量dc,用来访问SimpleCMSEntities的实例,代码如下:
private readonly SimpleCMSEntities dc = newSimpleCMSEntities();
分类树的Store调用的是List方法,因而将Index方法修改为List方法,并加入相应的权限、返回对象和基本结构代码,代码如下:
[AjaxAuthorize(Roles= "普通用户,系统管理员")]
publicJObject List()
{
bool success = false;
string msg = "";
JArray ja = new JArray();
int total = 0;
try
{
success = true;
}
catch (Exception e)
{
msg = e.Message;
}
returnHelper.MyFunction.WriteJObjectResult(success, total, msg, ja);
}
树展开一个节点,都会以node作为参数将该节点的id提交,因而,在提取数据是,首先要做的是先从node提取id,代码如下:
intid=-1;
int.TryParse(Request["node"], out id);
因为在定义Store时,根节点的id为-1,因而这里要分两种情况处理搜索结果,代码如下:
IQueryable<T_Category>q = null;
if (id== -1)
{
q = dc.T_Category.Where(m =>m.Hierarchylevel == 0 & m.State == 0).OrderBy(m=>m.Title);
}
else
{
q = dc.T_Category.Where(m => m.ParentId== id & m.State == 0).OrderBy(m => m.Title);
}
代码中,当id为-1时,就搜索层数为0的记录,否则,则搜索ParentId的等于id的记录。
这里有个问题,因为记录根据标题进行了排序,因而未分类这个类别就不知道跑到那个位置去了,因而,为了保持为分类在顶部,在查询的时候最好把它排除出去,另外再添加到结果中,代码修改如下:
q =dc.T_Category.Where(m => m.Hierarchylevel == 0 & m.CategoryId!=10000& m.Stat
补充:Web开发 , 其他 ,