CMS:文章管理之视图(5)
在完成文章管理功能前,先来完成文章列表工作。文章列表,都是在文章分类选择后执行的,因而要从文章类别的选择入手,文章管理的控制器Content.js中,文章类别的选择方法已经有了,是onTreeSelect方法,现在要做的就是完成文章列表的功能。在这里有2种方式可供选择,一种是使用Store的filter方法来实现筛选,一种是利用Proxy的extraParams配置项来完成。第一种方法的好处是可以通过MixedCollection对象来统一管理筛选对象,这在有多个搜索条件的时候非常使用,而它最大的问题是和之前做过的排序的方式一样,会以JSON数组形式提交数据,因而增加了后台处理的复杂度,这个就要根据项目需求进行选择了。第二种方法的好处就是后台处理简单,按习惯方式处理就行了。本示例只简单的演示简单的搜索,因而就不采用第一种方式了。
现在来完成列表的代码,在onTreeSelect方法内的判断语句内(有选择才去列表),在id的赋值语句下,添加以下代码:
var store=me.getContentsStore();
store.proxy.extraParams.CategoryId=id;
store.loadPage(1);
在这里,每次更新CategoryId后,调用一次loadPage加载第一页。这里为什么不用load方法呢?原因是直接用load方法,用户进行了一些分页操作的,会保留这些分页操作的结果,而加载的后果就是可能找不到数据了,譬如用户在查看全部文章的时候,查看到了第10页,然后切换到未分类,但是它并没有10页数据,而load方法并不知道,提交的还是提取第10页的数据,这样就出问题了。当然了,在设置参数的时候,把分页参数也设置一编,再调用load方法也是可行。但是,既然有更简捷的方法loadPage,Store会自动帮你处理了这些的东西的,又何必缘木求鱼呢?
现在,在服务器端,就可通过CategoryId来获取分类编号,下面来完成这个。在Controllers目录添加一个名为ContentController的控制器,设置好引用了私有变量SimpleCMSEntities,就可完成List方法了,代码如下:
[AjaxAuthorize(Roles = "普通用户,系统管理员")]
public JObject List()
{
boolsuccess = false;
stringmsg = "";
JArray ja= new JArray();
int total= 0;
try
{
intcategroyId = -99;
int.TryParse(Request["CategroyId"], out categroyId);
intstart = 0;
int.TryParse(Request["start"], out start);
IQueryable<T_Content> q = null;
string sort = Request["sort"] ?? "";
sort= Helper.MyFunction.ProcessSorterString(new string[]{"ContentId","Title","Created","SortOrder","Hits"}, sort, "it.ContentId ASC");
if(categroyId == -99)
{
q= dc.T_Content.Where(m => m.State == 0).OrderBy(sort);
}
else
{
q= dc.T_Content.Where(m => m.CategoryId == categroyId & m.State ==0).OrderBy(sort);
}
total= q.Count();
if(start > total) start = 0;
foreach (var c in q.Skip(start).Take(50))
{
ja.Add(new JObject {
new JProperty("ContentId",c.ContentId),
new JProperty("Title",c.Title),
new JProperty("Created",c.Created.ToString("yyyy-MM-ddhh:mm")),
new JProperty("SortOrder",c.SortOrder),
new JProperty("Hits",c.Hits),
newJProperty("Tag",string.Join(",",c.T_Tag.Select(n=>n.TagName).ToArray()))
});
}
success = true;
}
catch(Exception e)
{
msg =e.Message;
}
returnHelper.MyFunction.WriteJObjectResult(success, total, msg, ja);
}
代码中,排序把标签排除了,原因是要先处理出标签,才能排序,处理方式就是后面生成JSON对象时组合字符串的方法,然后再对该生成字段排序。
这里还有个问题要注意,就是当start大于记录总数时,也就是跳转值大于记录总数时,如果不修改,就会出错,因而必须进行处理,处理方式可根据自己喜好进行调整,这里只是简单的设置回第一页。
代码中还没添加搜索,这个等下再加。
因为没有数据,暂时测试不了。如果心急,可以自己在数据库加点数据测试。
现在,把分页工具条加到Grid面板上,并添加3个按钮用来实现添加、编辑、删除和查看操作。这个难度不大,应该很熟悉了,在视图中创建Grid的JSON对象中加入以下代码就行了:
tbar: {
xtype:"pagingtoolbar",
pageSize:50, displayInfo: true, store: "Contents",
items: [
'-',
{iconCls: "add", scope: me, tooltip: '增加文章', id:"ContentButtonAdd"},
{iconCls: "edit", scope: me, tooltip: '编辑文章', id: "ContentButtonEdit", disabled: true },
{iconCls: "delete", scope: me, tooltip: '删除文章', id:"ContentButtonDelete", disabled: true },
{iconCls: "view", scope: me, tooltip: '查看文章', id: "ContentButtonView", disabled: true },
'-'
]
},
这里的关键还是id,要让控制器能方便的找到按钮。
别忘了在app.css中加入按钮图标的样式定义,代码如下:
.add{
background:url("../images/page_white.png")!important;
}
.edit{
background:url("../images/page_white_edit.png")!important;
}
.delete{
background:url("../images/page_white_delete.png")!important;
}
.view{
background:url("../images/page_white_magnify.png")!important;
}
在浏览器中打开文章管理就会看到如图57中所示的效果了。
图57 添加了分页工具栏的Grid
现在,在控制器中添加按钮的引用,和添加文章类别的按钮引用没什么区别,代码如下:
{ ref: "ContentAdd", selector:"#ContentButtonAdd" },
{ ref: "ContentEdit", selector:"#ContentButtonEdit" },
{ ref: "ContentDelete", selector:"#ContentButtonDelete" },
{ ref: "ContentView", selector:"#ContentButtonView" }
接着,绑定事件,代码如下:
me.getContentAdd().on("click",me.onContentAdd, me);
me.getContentEdit().on("click",me.onContentEdit, me);
me.getContentDelete().on("click",me.onContentDelete, me);
me.getContentView().on("click",me.onContentView, me);
下面要完成的是Grid的某一行选择后,启用编辑、删除和查看按钮,难度不大,绑定Grid的selectionchange事件就行了,代码如下:
me.view.down("gridpanel").on("selectionchange",me.onContentSelect, me);
再完成onContentselect方法,代码如下:
onContentSelect: function (model, sels) {
var me =this
me.getContentEdit().setDisabled(sels.length == 0);
me.getContentDelete().setDisabled(sels.length== 0);
me.getContentView().setDisabled(sels.length == 0);
}
顺便把Grid刷新列表时选择第一行也完成了,代码如下:
me.view.down("gridpanel").getView().on("refresh",function () {
var me =this;
if(me.getContentsStore().getCount() > 0) {
me.view.down("gridpanel").view.select(0, true);
}
}, me);
好了,一些基本操作已经完成了,现在要完成的是添加和编辑操作需要用到的弹出窗口了,下文再说。