ASP.NET MVC异步验证是如何工作的03,jquery.validate.unobtrusive.js是如何工作的
在上一篇"ASP.NET MVC异步验证是如何工作的02,异步验证表单元素的创建"中了解了ASP.NET异步验证是如何创建表单元素的,本篇体验jquery.validate.unobtrusive.js异步验证的全过程。
在jquery.validate.unobtrusive.js文件的尾部看到了如下的一个调用:
$(function () {$jQval.unobtrusive.parse(document);});
可见,通过把当前页的document对象传给$jQval.unobtrusive.parse方法,使该页的表单元素能被异步验证。parse方法的主要作用是对所有的表单进行异步验证。
{parse: function (selector) {$(selector).find(":input[data-val=true]").each(function () {$jQval.unobtrusive.parseElement(this, true);});var $forms = $(selector).parents("form").andSelf().add($(selector).find("form")).filter("form");$forms.each(function () {var info = validationInfo(this);if (info) {info.attachValidation();}});}}
以上,首先遍历data-val=true的input元素,调用$jQval.unobtrusive.parseElement方法,把存在于html元素中的、有关异步验证的信息抓取出来封装成jquery.validate.unobtrusive.js能识别的元数据。$jQval.unobtrusive.parseElement方法的第一个参数表示被验证的表单元素。第二个参数为true时,表示跳过对表单元素的验证,如果只验证一个元素就设置成true,如果验证多个元素就设置成false,默认为false。
在validationInfo这个对象中,包含了异步验证所需要的一切信息,当调用attachValidation方法的时候,就会把封装在validationInfo对象中的所有验证规则传给validate方法。
有关validationInfo的细节:
data_validation = "unobtrusiveValidation";function validationInfo(form) {var $form = $(form),result = $form.data(data_validation),onResetProxy = $.proxy(onReset, form);if (!result) {result = {options: { // options structure passed to jQuery Validate‘s validate() methoderrorClass: "input-validation-error",errorElement: "span",errorPlacement: $.proxy(onError, form),invalidHandler: $.proxy(onErrors, form),messages: {},rules: {},success: $.proxy(onSuccess, form)},attachValidation: function () {$form.unbind("reset." + data_validation, onResetProxy).bind("reset." + data_validation, onResetProxy).validate(this.options);},validate: function () { // a validation function that is called by unobtrusive Ajax$form.validate();return $form.valid();}};$form.data(data_validation, result);}return result;}
以上,在validationInfo的构造函数中,通过$form.data方法,可以获取或设置unobtrusiveValidation的值。在unobtrusiveValidation这个对象中,包含了异步验证所需要的信息:
1、名为options的json对象,包含了验证规则、错误信息等。
2、attachValidation方法用来给form绑定自定义事件,每次调用或解除reset.unobtrusiveValidation方法都会调用onReset方法。
function onReset(event) { // ‘this‘ is the form elementvar $form = $(this);$form.data("validator").resetForm();$form.find(".control-group").removeClass("error");$form.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");$form.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*") // If we were using valmsg-replace, get the underlying error.removeData("unobtrusiveContainer");}
3、validate表示可以自定义验证事件。
而在把validationInfo对象中的所有验证规则传给validate方法的时候,真正起作用的是$.validator.unobtrusive.adapters,这样html中以data-*开头的才能被validate方法读懂。如果需要自定义异步验证规则,需要通过jQuery.validator.unobtrusive.adapters.add(adapterName, [params], function(element, form, message, params, rules,messages){})方法来实现。
其中,adapterName与data-val-ruleName中的ruleName匹配。通过adapter可以扩展如下:jQuery.validator.unobtrusive.adapters.addBool(adapterName, [ruleName]);
jQuery.validator.unobtrusive.adapters.addSingleVal(adapterName, attribute, [ruleName]);
jQuery.validator.unobtrusive.adapters.addMinMax(adapterName, minRuleName, maxRuleName, minMaxRuleName, [minAttribute, [maxAttribute]]);