昨天还有一个错误,CheckColumn的样式和图片没复制过来,造成最后一列的Checkbox显示不正确。在Ext JS包的examples\ux\css目录下打开CheckHeader.css文件,将文件里的全部样式定义复制到app.css中。然后修改将带背景图片的路径修改为“../images”。最后将image目录下的check.gif和uncheck.gif文件复制到scripts\app\resources\images目录下。
接下来要完成的是用户管理的余下功能。
首先切换到用户视图脚本文件,为Grid添加一个RowEditing插件,这不难,创建RowEditing的实例,并添加到plugins就行了,代码如下:
me.rowEditing=Ext.create('Ext.grid.plugin.RowEditing', {
autoCancel:false,
saveBtnText: '保存',
cancelBtnText: '取消',
errorsText:'错误',
dirtyText:"你要确认或取消更改"
});
me.plugins=[me.rowEditing];
代码中,RowEditing设置了autoCancel为false,表示用户必须单击取消按钮才能退出编辑状态,这样可避免一些难以预料的状态发生。RowEditing一些文本信息其实可以在本地化文件中汉化,这里只是演示使用方法。
现在,要为用户名、电子邮件、角色和禁用列添加编辑控件了,这个只要定义好editor配置项就可以了,修改后的代码如下:
me.columns= [
{ text: '用户名', dataIndex: 'Username', flex: 1 ,
editor: { allowBlank: false}
},
{ text: '电子邮件', dataIndex: 'Email', flex: 1 ,
editor: { allowBlank: false, vtype: 'email' }
},
{ text: '角色', dataIndex: 'Roles', flex: 1 ,
editor:{
xtype: 'combo',store:'Roles',multiSelect:true,allowBlank:false,editable:false,
emptyText:"请选择角色",forceSelection:true
}
},
{ xtype: "datecolumn", text: '创建时间', dataIndex: 'Created', format:"Y-m-d H:i:s", width: 150 },
{ xtype: "datecolumn", text: '最后登录时间', dataIndex: 'Created', format:"Y-m-d H:i:s", width: 150 },
{ xtype: 'checkcolumn', dataIndex:"IsApproved", text: "允许登录", winth: 150 ,
editor: {xtype: 'checkbox',cls:'x-grid-checkheader-editor'}
}
]
代码中,用户名只是简单的不允许为空;电子邮件除了不允许为空外,还要符合电子邮件格式(vtype为email);角色则使用Combobox,数据来自之前定义的Roles Store;禁用列则使用了Checkbox控件,样式使用x-grid-checkheader-editor,这样好看点。
接着在分页工具栏添加3个按钮,其中添加用户、删除用户使用图标显示,而重置密码则直接使用文字按钮。要在按钮显示图标,最好的方式使用样式,因而,先切换到app.css,添加以下样式:
.user-add{
background:url("../images/user-add-16.png")!important;
}
.user-delete{
background:url("../images/user-delete-16.png")!important;
}
这里用到了2个图片文件,将它们复制到scripts\app\resources\images目录下。
复制后,切换回用户视图脚本文件,在分页工具栏定义中加入items配置项来添加按钮,代码如下:
items:[
'-',
{ iconCls: "user-add", tooltip: '添加用户', id:"buttonUserAdd"},
{ iconCls: "user-delete",tooltip: '删除用户',id:"buttonUserDelete",disabled:true},
'-',
{text:"重置密码",id:"buttonUserResetPassword",disabled:true}
]
注意,按钮全部都添加了id,目的就是在控制器中使用id查找按钮。删除用户和重置密码默认状态为disabled状态,只有在Grid选择行后才会启用。
现在,可以测试一下效果了,在浏览器打开页面,登录后切换到用户管理,双击第二条记录,将看到如图27所示的效果,界面显示正常。
图27 添加RowEditing后的用户视图
现在,要在控制器完成各种视图操作了。切换到Users控制器,先添加一些引用来获取视图和按钮,代码如下:
refs: [
{ ref: "UserPanel", selector: "#userPanel"},
{ ref: "UserView", selector: "#usersView"},
{ ref: "ButtonUserAdd",selector: "#buttonUserAdd" },
{ ref: "ButtonUserDelete",selector: "#buttonUserDelete" },
{ ref: "ButtonUserResetPassword", selector: "#buttonUserResetPassword" },
],
这样,就可通过get方法获得各控件了。
首先来完成选择一条记录后,启用删除和重置密码按钮。实现相当简单,利用引用,使用getUserView返回用户视图后,调用on方法绑定selectionchange事件就行了。当然也可以在control方法内定义,不过笔者感觉再用id获取一次对象,有点多余。在panel.add这句下加入以下代码:
me.getUserView().on("selectionchange", me.onUserSelect, me);
在onUserSelect方法内,利用get方法返回两个按钮后,调用对象的setDisabled方法设置其开启状态就可以了,代码如下:
onUserSelect:function(model, rs){
var me=this,
length=rs.length;
me.getButtonUserDelete().setDisabled(length==0);
me.getButtonUserResetPassword().setDisabled(length == 0);
}
事件selectionchange会在第二个参数以数组形式返回所有选择的记录,只要数组的长度不为0,就启用按钮的,为0则禁用按钮。
接着完成添加操作,在绑定selectionchange事件的代码下添加以下代码绑定click事件:
me.getButtonUserAdd().on("click",me.onAddUser, me);
在onAddUser方法内,要做的操作是先调用cancelEdit取消当前编辑操作,以避免在编辑过程中单击了添加按钮出现问题。接着在Store中添加一条记录。最后调用startEdit方法进入编辑状态。具体代码如下:
onAddUser: function () {
var me = this
edit = me.getUserView().plugins[0],
User = me.getUserModel();
edit.cancelEdit();
me.getUsersStore().insert(0, new User);
edit.startEdit(0, 0);
}
代码中,getUserModel是定义models配置项时自动生成的方法,可返回模型。同理,getUsersStore方法也是自动生成的,用于返回Store。要注意plugins中的索引,因为当前示例只有一个插件,因而使用0就可以返回RowEditing实例了,如果有多个插件,要注意索引值。
接下来要考虑怎么保存数据了,在RowEditing有一个Edit事件,它会在编辑完成后触发,非常适合用来进行数据保存操作。而且该事件会把事件冒泡到Grid,因而在Grid绑定该事件就行了,代码如下:
me.getUserView().on("edit",me.onEditcomplete, me);
在onEditcomplete方法内,调用Store的sync方法将数据同步到服务器就行了,代码如下:
onEditcomplete: function (editor, e) {
var me = this;
me.getUsersStore().sync({
success: function (e, opt) {
var me = this;
me.getUsersStore().commitChanges();
},
failure: function (e, opt) {
var me = this, msg = "";
me.getUsersStore().rejectChanges()
Ext.Msg.alert("错误", e.exceptions[0].error);
},
scope: me
});
}
如果同步操作,服务器返回success为true,则调用commitChanges方法确认修改,如果失败,则调用rejectChanges方法取消修改,并显示错误信息。错误信息的处理与上文的处理差不多,只是返回的对象不同,自己根据需要做好定义就行了。
还有考虑用户取消编辑时,要调用rejectChanges方法取消更改,这个通过监听canceledit事件就可以实现,代码如下:
me.getUserView().on("canceledit",me.onCancelEdit, me);
方法onCancelEdit的代码如下:
onCancelEdit :function(){
var me=this;
me.getUsersStore().rejectChanges();
}
图28 添加操作提交数据的格式
现在要在服务器端完成用户的添加功能了,这里要注意的是数据的提交方式。如果不清楚,可在页面单击添加按钮,然后单击保存按钮,在Firebug中就可以看到如图28所示的提交数据。 在服务器端的处理过程就是通过data提取数据,然后转换为JSON数组,从数组中把数据提取出来。对于添加操作,调用Membership的CreateUser方法添加用户就可以了,具体代码如下:
publicJObject Add()
{
bool success = false;
string msg = "";
JArray ja = null;
try
{
string data = Request["data"]?? "";
if (string.IsNullOrEmpty(data))
{
msg = "错误的提交数据。";
}
else
{
ja = JArray.Parse(data);
if (ja.Count > 0)
{
JObject jo = (JObject)ja[0];
MembershipCreateStatuscreateStatus;
MembershipUser user =Membership.CreateUser((string)jo["Username"], "123456",(string)jo["Email"], null, null, (bool)jo["IsApproved"],out createStatus);
if (createStatus ==MembershipCreateStatus.Success)
{
success = true;
string[] roles =((JArray)jo["Roles"]).Values<string>().ToArray<string>();
jo["id"]=user.ProviderUserKey.ToString();
jo["Created"] =user.CreationDate.ToString("yyyy-MM-dd hh:mm:ss");
jo["LastLoginDate"] =user.LastLoginDate.ToString("yyyy-MM-dd hh:mm:ss");
Roles.AddUserToRoles(user.UserName, roles);
}
else
{
msg=MyFunction.ErrorCodeToString(createStatus);
}
}
else
{
msg = "错误的提交数据。";
}
}
}
catch (Exception e)
{
msg = e.Message;
}
returnMyFunction.WriteJObjectResult(success, 0, msg, ja);
}
这里要注意的事项是,如果创建成功,必须返回最终数据以更改客户端的信息,主要是更新用户id,因而数据的返回格式与列表返回的格式相同。还要在MyFunction中实现ErrorCodeToString方法,用来将错误代码转换为信息返回,在这里就不列了,有兴趣自己下载代码看。
编辑用户的操作过程与添加操作雷同,不过Membership不允许修改用户名,因为最好在编辑的时候,不允许用户修改用户名。这个需要在RowEditing进入编辑之前来控制编辑控件的状态,也就是在beforeedit事件中实现。先在Grid绑定beforeedit事件,代码如下:
me.getUserView().on("beforeedit",me.onBeforeEdit, me);
在onBeforeEdit方法内,要对用户名的编辑组件进行操作,因而要为它添加一个引用,那就要先为编辑控件添加一个id,在用户视图脚本文件内,为用户名的编辑控件添加一个id:
然后在控制器加入引用:
{ ref: "editorUserName",selector: "#editorUserName" }
现在完成onBeforeEdit方法,代码如下:
onBeforeEdit: function (editor, e) {
var me = this;
if (e.record.data.id) {
me.getEditorUsername().setDisabled(true);
} else {
me.getEditorUsername().setDisabled(false);
}
}
编辑的数据都有id,而新增的数据id为null,因而通过判断id就可判断是编辑数据还是新增数据,从而可控制用户名是否允许编辑了。这也是为什么在添加数据后必须返回正确的id的一个重要原因。
现在可完成服务器端的编辑操作代码了,具体代码如下:
public JObject Edit()
{
bool success = false;
string msg = "";
JArray ja = null;
try
{
string data = Request["data"] ?? "";
if (string.IsNullOrEmpty(data))
{
msg = "错误的提交数据。";
}
else
{
ja = JArray.Parse(data);
if (ja.Count > 0)
{
JObject jo = (JObject)ja[0];
Guid id = Guid.Parse((string)jo["id"]);
MembershipUser user = Membership.GetUser(id);
if (user!=null)
{
user.Email = (string)jo["Email"];
user.IsApproved = (bool)jo["IsApproved"];
Membership.UpdateUser(user);
string[] roles = ((JArray)jo["Roles"]).Values<string>().ToArray<string>();
string[] oldroles = Roles.GetRolesForUser(user.UserName);
string[] rolelist = new string[] { "普通用户", "系统管理员" };
foreach (var c in rolelist)
{
if (roles.Contains(c))
{
if(!oldroles.Contains(c))
{
Roles.AddUserToRole(user.UserName,c);
}
}
else
{
if (oldroles.Contains(c))
{
Roles.RemoveUserFromRole(user.UserName,c);
}
}
}
success = true;
}
else
{
msg = "要修改的用户不存在或已被删除。";
}
}
else
{
msg = "错误的提交数据。";
}
}
}
catch (Exception e)
{
msg = e.Message;
}
return MyFunction.WriteJObjectResult(success,0, msg, ja);
}
获取数据的方式与返回数据的方式是一样的。最简单的角色操作是先把用户原有的角色全部删除,然后再添加新的角色。这里则使用了另一种方法,遍历所有的角色,然后判断新设置的角色是否包含该角色,如果包含,而旧有角色又不包含,则调用AddUserToRole方法添加角色。如果不包含,则判断旧有角色是否包含,如果包含,就调用RemoveUserFromRole方法删除角色。
好了,今天到这里,明天继续。
源代码下载:http://download.csdn.net/detail/tianxiaode/4603702
分享到:
相关推荐
《一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建项目》的项目文件
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建Viewport(2)源代码
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(2) 源代码
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(4) 源代码
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之创建Viewport(1)
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之数据库文件
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之登录窗口调试代码
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之用户管理(3) 源代码
一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之调整首页显示
ext asp.net mvc nhibernate 完整项目示例
本例采用ASP.NET MVC3 +EXTJS4 MVC 框架,完美实现了EXTJS4动态加载JS文件,对ASP.NET MVC3及EXTJS4 MVC 各应用要点进行了应用。对于想采用ASP.NET MVC3 +EXTJS4 MVC 框架的学习者有很好的帮助,快速掌握MVC框架,本...
extasp.net 是个不错的asp.net 源码,mvc+ext+三层架构
本资源为学习asp.net mvc+ext js的用户提供一个简单的增、删、改功能。通过此例子对MVC和Ext js有一个初步的认识,压缩包内的mvcStudent.sql为数据库脚本。
Ext.Direct.Mvc是ASP.NET Mvc.的Ext Direct服务器端堆栈的实现.zip
本源代码包来源于Ext.NET官方网站,于2012-07-24日发布,可以用Visual Studio 2010打开后进行编译,但需要先安装ASP.NET MVC3。此源代码包目前官网上已经没有下载了!目前官网的最新版本是2.1.1,但是有BUG。 本源...
可以快速上手开发企业的信息管理系统,也可提供oracle 11g版本框架非常适合二次开发人员使用, 强烈推荐一下,感兴趣的欢迎下载看看啊。 二、框架简介 1、数据持久层使用IBatis.Net ORM 映射框架, 提供了较为灵活...
程序结构是asp.net MVC,使用EXT3.1,从服务器端读取数据 运行前先建一个ext3.1的虚拟目录 说明:treegrid中数据的关系: RoleType表: RoleTyptID RoleTypeName 1 系统管理 2 管理员 Role表: RoleID ...
Quickly Build Rich AJAX Enabled Web Applications For ASP.NET Ext.NET is an open source ASP.NET (WebForm + MVC) component framework integrating the cross-browser Sencha Ext JS JavaScript Library
在ASP.NET mvc模式下使用Extjs搭建的框架页面代码