吐槽一次MVC与Jq EasyUI的经历
MVC在Web开发中的优势(在TDD方面、逻辑与UI的彻底分离)已无需多言,除此之外个人感觉在给UI提供JSON各式的数据也更加方便。
但是总体上说,在公司的这次MVC经历最后的感觉还是比较失败。个人记录下来在此做个反思,同时希望和大家一起交流,向大家学习。
整体项目截图如下:
(图1)
首先从以上截图中, 个人就犯错了。从整体架构上来说,项目中的授权部分(Accredit )之前是希望通过AOP的方式进行的,最后和在基础加上的AOP部分就发生了剧烈的冲突。这是一个非常致命的错误!导致只有的AOP上无法进行。
接下来的问题,注意体现就是EasyUI上了。
1、EasyUI数据绑定
EasyUI 在统计数据表中比较方便。数据只要有只有配置响应的字段名称就可以很方便的进行绑定。个人目前知道有两种方式:
方式一、
在页面的加载的时候,使用datagrid方法进行。如下代码:
iconCls: 'icon-save',
nowrap: false,
striped: true,
url: '<%Url.Action("LoadMyPostMeetings") %>',
remoteSort: true,
fitColumns: true,
fit: true,
width:'auto',
height:'auto',
idField: 'Guid',
frozenColumns: [[
{ field: 'Id', checkbox: true }
]],
columns: [[
{ field: 'Title', title: '标题', width: 80, align: 'left'},
{
field: 'Time',
title: '时间',
width: 60,
align: 'left',
formatter: function(value) {
var date = (new Date(parseInt(value.substring(value.indexOf('(') + 1, value.indexOf(')')))));
return date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
}
},
{
field: 'ImportantLevel',
title: '重要等级',
width: 30,
align: 'left',
formatter: function(value) {
switch (value) {
case 0:
return "普通";
case 1:
return "重要";
default:
return "非常重要";
}
}
},
{ field: 'Address', title: '会议地点', width: 40, align: 'left' }
]],
pagination: true,
rownumbers: true,
onLoadSuccess:function (data){
if(data.Identity) {
for (var i = 0; i < data.rows.length; i++) {
if (data.rows[i].IsCompleted == 1) {
$(".datagrid-body >table tr").eq(i).find("td:last").find("a").eq(1).removeAttr("href").removeAttr("onclick").attr("title", "已关闭");;
}
}
} else {
for (var k = 0; k < data.total; k++) {
$(".datagrid-body >table tr").eq(k).find("td:last").find("a").eq(1).removeAttr("href").removeAttr("onclick").attr("title", "已关闭");;
}
}
}});
这种方式可以在代码中对所要绑定的数据进行格式化,如以上代码中的formatter 。
方式二、由表定义需要显示的字段名称,datagrid函数获取数据进行绑定。如下:
<thead>
<tr>
<th checkbox="true" field="Guid" />
<th field="UserName" sortable="true" width="25%">用户名</th>
<th field="AccountName" sortable="true" width="25%">账号</th>
<th field="BeginIP" sortable="true" width="25%">起始IP</th>
<th field="EndIP" sortable="true" width="25%">截止IP</th>
</tr>
</thead>
</table>
$('#userTable').datagrid({
title: '账号列表',
iconCls: 'icon-save',
nowrap: false,
striped: true,
url: '<%=Url.Action("LoadUsers") %>',
remoteSort: true,
fitColumns: true,
fit: true,
idField: 'Guid',
frozenColumns: [[
{ field: 'Id', checkbox: true }
]] });
当然 ,像一些EasyUI中设置表格是否分页等信息也可以在表格的HTML中进行设置,datagrid只获取JSON格式的数据然后对表格进行绑定。
总结:比较绑定表格的这两种方式,我发现:
一、第一种虽然需在JS中定义需要显示的字段数据,但是对数据可以方便的进行格式化。第二种方式,直接在表格中定义需显示的字段,却不太好对数据进行格式化。
二、在使用datagrid对表格进行数据绑定的时候, 获取数据的URL信息(如:url: '<%=Url.Action("LoadUsers") %>')在以后是不能变更的。这里的不能变更指的是不能换成另外一个Action进行获取另外的JSON数据对表格进行绑定处理。 当然,如需使用同一个Action进行处理,只是在Action中的参数不同,还是可以这样使用的。
可能以上第二点中说的不是文字表述的不是特别清楚明了,我这里举例进行说明.
(图2)
如上图,在表格上方有一组操作方法,在其中的【搜索】中,我弹出一个DIV,选中条件然后重新获取数据对表格进行绑定。这时,获取到JSON数据后,这样对表格进行重新绑定:
$("#userTable").datagrid('reload',jsonDatas)
这样,由于对表格进行reload,又重新指定数据源,表格是显示了正确数据。但是,若此时,对表格的查询结果进行分页,则表格显示的数据不再是查询获取到的数据,而是重新返回到有datagrid中设置的url: '<%=Url.Action("LoadUsers") %>'在你选定的分页上的数据。问题就比较悲剧了。
在这点上,EasyUI也有一种解决问题的方式将 你选定的条件发送到Url指定的Controller进行处理,如下:
$("#userTable").datagrid('load',{'key1':'value1','key2':'value2'});
当然,url所指定的Action中需有key1、key2这样的参数。
2、 为列表指定操作区:
为列表指定操作区,如图2。同表格的绑定方式一样,同样有两种方式。
方式一、在表格的datagrid方法中中,通过toolbar指定:如下代码:
/* 前面表格部分同上,在此省略*/
toolbar: ['-', {
id: 'btnSave',
text: '添加',
iconCls: 'icon-add',
handler: function() {
this.href = '<%=Url.Action("AddMeeting1") %>/';
}
},
'-', {
id: 'btnUpdate',
text: '修改',
iconCls: 'icon-edit',
handler: function(msg) {
var row = $('#grid').datagrid('getSelected');
if (row) {
this.href = '<%=Url.Action("AddMeeting1") %>' + "/" + row.Guid;
} else {
$.messager.alert('提示', '请选择要修改的数据');
return;
}
}
});
方式二、在表格的HTML中使用easyUI中的toolbar指定。如下代码:
</table>
<div id="toolbar">
使用人姓名:<input type="text" name="searchName" id="searchName" />
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-search" plain="true" onclick="check()">查询</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="newUser()">增加</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-edit" plain="true" onclick="editUser()">修改</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-remove" plain="true" onclick="removeUser()">删除</a>
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="ShowImportUsers()">导入用户数据</a></div>
这两张方式倒是没有什么不同,只是在第一种方式中,如果要有一个查询的输入框(如下图三:):不知如何写一个input标签到配置的toolbar中,因此第二种方式更占优势。
3、 在表格的datagrid中设定多少行为已经选中
通常,为了操作批量操作,一般都会在表格第一列显示一个CheckBox。在通过JS,也很容易地将Checkbox勾选上,代码如下:
$(".datagrid-body input[type=checkbox]:eq(" + i + ")").attr("checked", "checked");
}
但是千万别以为这样操作了就万事大吉,最重要的问题还有待解决。
在EasyUI中,如果我们将表格手动勾选上以后,是通过$("#userTable").datagrid('getSelections')获取选中的行的。但是以上将Checkbox勾选上的JS,固然是将Table中的行选中了,但通过$("#userTable").datagrid('getSelections')是获取不到行的。
如何将EasyUI绑定的表格行通过JS“真正”绑定上呢,? 答案就是$("#userTable").datagrid('selectRow', i) 。
4、combogrid中的搜索问题:
EasyUI中的combox 也就<Select>,可以手动输入。可以使用如下代码将它动态进行绑定:
panelWidth: 155,
idField: 'Guid',
textField: 'UserName',
fit:true,
url: '<%=Url.Action("LoadUserDatas") %>',
columns: [[
{ field: 'UserName', title: '姓名', width: 60 },
{ field: '', title: '部门', width: 100 }
]]});
同datagrid一样,也是通过url指定的Action进行数据获取。
(图4)
由于我这输入后,需要通过选择的文本获取人员的GUID,然后写入库,这种方式可以实现,下拉表中如果搜索到,人员的会自动被选中。也无需单独处理。