前端基于easyui的mvc扩展(续)
回顾及遗留问题
上一篇讲解了基于easyui的mvc扩展的基本实现,已经降低了在mvc内使用easyui的难度,但是仍然还有一些问题:
- 当我们要给生成的控件设置一些其他的属性(如:id)或者想要设置easyui控件的一些其他的可配置项
- 对于form表单提交时,也要让form表单基于easyui的验证机制来进行验证
这里要先提一下,上一篇的TagBuilder并不是微软自带的(位于System.Web.Mvc下),而是自己实现的,理由嘛,既然我们编码了mvc下对于easyui的扩展,那么同样也可以去扩展普通的web form(后面的文章会再进行扩展),TagBuilder的实现方式跟微软提供的很相像,大家自己实现吧,^_^。
实现
由于所要增加的额外属性是以key、value方式存在的,如:id="myId" or onclick="findRecords"等,那么我们看以通过增加一个Dictionary<string, string>参数的方式来将我们需要的配置传给构造easyui html的方法,大致的代码如下:
Html.Combobox(m => m.StateId, "States", new Dictionary<string, string> { { "id", "cboState" }, { "data-options", "width: 100, editable: false" } })
TagBuilder内只要对传入的字典进行此存储,然后在生成Html的时候将KeyValuePair<string, string>转化为key="value"形式的字符串就可以了。
而对于form表单结合easyui的验证原本easyui便提供了form表单的功能,只需要我们使用如下代码,便可以进行验证:
$('#myForm').form({ onSubmit: function(){ var isValid = $(this).form('validate'); return isValid; }, success: function(data){ //这里不像jQuery那样可以返回json对象,data永远都是一个字符串,除非使用ajax form表单进行自己的扩展 } });
由于mvc内对于表单验证已经提供了支持,但是因为我们自己进行了自定义的扩展,那么在执行controll的Action的时候,mvc虽然会帮我们对表单的实体进行验证,但并不会主动在验证失败的情况下阻止Action的执行,因此我们需要自己寻找其他的方式在表单实体验证失败的情况下,将失败的信息返回到客户端进行提示。
我们知道所有的Controller都继承自System.Web.Mvc.Controller(它是继承自IController的),System.Web.Mvc.Controller有一个受保护的OnActionExecuting方式,当我们对方法的ActionExecutingContext的Result进行赋值的情况下,它会阻止原本要继续执行的Action的触发,而且Result内的值会回传给客户端,因此我们可以在此方法内对于表单实体是否验证失败来完成我们的操作,代码如下:
protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (ViewData.ModelState.IsValid) { base.OnActionExecuting(filterContext); } else { filterContext.Result = Content("{\"success\":false, \"message\":\"表单数据异常\"}"); } }
这里要注意了,如果使用mvc自带的Json方法来回传数据的话,传递到客户端永远都只是{},这里大家可以使用Json.Net来将对象转化为json。
到了这里,该有的功能我们基本上都已经完成了,其实还有一些小问题没有解决,那就是当我们配置控件属性的时候,如果是函数的情况下,就只能将函数必须是全局的或者要写在属性的值里面,实在很不方便,或者大家可以跟我一样,用其他的属性来代替这些配置,我使用的方式如下:
@Html.Combobox(m => m.StateId, "States", new Dictionary<string, string> { { "easyui", "onSelect:selectState,formatter:formatterState" } }) @Html.Linkbutton("上传", new Dictionary<string, string> { { "bind": "click:uploadFile" } })
然后在js文件或者<script>脚本内对以上的格式进行解析,这样就可以根据自己的方式来声明函数了。
其次就是老是要写一大串的字典来声明额外的属性实在是很麻烦的事情,那么也可以使用json的方式将字符串直接写入,代码如下:
@Html.ValidatePassword(m => m.Password, @"{ validType: 'remote[\'/user/CheckPassword\', \'password\']', invalidMessage: '密码有误!' }")
那么只要在后台将其解析为Dictionary<string,string>就可以了,方便了许多,有其他喜欢的格式也可以自己去定义,然后编码相关的解析方法也是可以实现的。
那么今天的后续部分就到这里结束了,有错误的地方请大家指出,谢谢大家!