【问题标题】:Avoiding validation loop in jQuery unobtrusive validation避免 jQuery 不显眼验证中的验证循环
【发布时间】:2013-07-21 03:12:03
【问题描述】:

在我的表单中有两个字段,它们相互比较以查看它们是否有效:

<input type="text" name="StartDate" id="StartDate" value="2"
       data-val="true" data-val-equalto="xx" data-val-equalto-other="EndDate"/>   
<input type="text" name="EndDate" id="EndDate" value="3"
       data-val="true" data-val-equalto="xx" data-val-equalto-other="StartDate"/> 

当我对StartDate 进行模糊处理时,EndDate 也会得到验证。所以 jQuery 设法避免了两者之间的验证循环。

现在,我正在尝试在我的自定义验证规则中实现相同的机制。我从“其他”字段中获取值,如果一切正常,我也会在“其他”字段中触发验证,但这会以验证循环结束:

$.validator.addMethod("customequal-method", function (val, el, p) {
    var $other = $(el).closest('form').find('input[name=' + p.other + ']'); 
    if($other.val() == val){        
        try{$other.valid();}
        finally{return true;}
    }
    return false;
});

我如何应用与 jQuery 相同的方法?我的意思是,鉴于这两个字段:

<input type="text" name="StartDate2" id="StartDate2" value="2"
       data-val="true" data-val-customequal="xx xxx" data-val-customequal-other="EndDate2"/>   
<input type="text" name="EndDate2" id="EndDate2" value="3"
       data-val="true" data-val-customequal="xx xx" data-val-customequal-other="StartDate2"/> 

我希望在修改 EndDate2 时,在模糊之后,StartDate2 也得到验证,并且两者都以与 jQuery 相同的方式变为有效。

我一直在尝试在 jsFiddle 中整理一个示例,但我无法使我的自定义方法工作:http://jsfiddle.net/vtortola/vu6tm/(如果您发现问题,我将非常感激),我在@987654322 开始了一个单独的线程@

干杯。

【问题讨论】:

  • 所以在您的视图模型中,您有开始日期和结束日期,使用 Unobtrusive(自定义验证),您想验证开始日期和结束日期。对吗?
  • 对。这只是具有两个相互比较的字段的示例。这个想法是,例如,在验证 StartDate2 之后,EndDate2 也会得到验证(因为它依赖于 StartDate2,并且它已经改变了)。干杯。

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 unobtrusive-validation unobtrusive-javascript


【解决方案1】:

您需要一个堆栈来了解您返回到之前验证过的元素。单个值是不够的,因为每个元素可能与其他元素一起参与其他规则。您可以在闭包中定义包含堆栈的 var(isInStack 验证元素是否在数组中):

(function () {
var stack = [];
$.validator.addMethod("customequal-method", function (val, el, p) {
var iAmTheRoot = stack.length == 0;
var $other = $(el).closest('form').find('input[name=' + p.other + ']'); 
if($other.val() == val){        
    try{
      if (!isInStack($other[0]) ) $other.valid();
    }
    finally{
    if (iAmTheRoot) stack = [];
    return true;}
}
return false;
});})();

【讨论】:

  • 但是该堆栈变量将为使用该方法的所有输入和执行共享?我需要在第一次调用该方法时创建该堆栈,然后在其余的执行过程中执行该堆栈,但不影响其他字段或规则。
  • 不,堆栈不被不同的执行和输入共享,只有包含它的变量被共享,但这不是问题,因为 javascript 没有并行线程,所以变量被不同的组访问不同时间间隔的合作输入。当一个根输入开始验证时,它从一个空堆栈开始,在对其他验证方法的递归调用返回后,根输入销毁它使用的堆栈,并用一个空堆栈替换它,因此另一个输入可以从一个空堆栈开始。此外,如果变量是共享的,则不可能发生干扰
  • 任何其他解决方案都需要重新定义验证器对象方法(这不是戏剧性的......我经常这样做)。一个更简单的解决方案是将规则仅应用于两个输入中的一个,并以这样一种方式进行管理,即更改处理程序附加到第二个输入,每次第二个输入更改时触发第一个输入的验证(我选择了这个实现连接到其他输入的动态最小和最大规则的技术)。
  • 它似乎工作正常。让我进一步测试一下:)
  • 好方法。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
相关资源
最近更新 更多