如何让不显眼的jquery远程验证器执行异步..?

dan*_*wig 7 jquery jquery-validate unobtrusive-validation asp.net-mvc-3 remote-validation

在MVC3应用程序中,使用jquery不显眼的验证,以及带有[Remote]验证器的视图/模型:我正在尝试禁用提交按钮并在远程验证期间显示等待图标,并且当有效表单提交给服务器时.我以为我已经把它钉在了IE8上.

问题是,当表单无效时,GC和FF没有触发表单的提交事件,因此我在此事件期间禁用了提交按钮.但是,当表单无效时,IE8会触发此事件,导致用户永远无法再次单击它.(IE8不提交表单,但事件被解雇.)

我尝试将一个函数附加到提交按钮的单击事件.在那里,我禁用了提交按钮,显示了等待图标,并且有:

$('[data-app-form-submit-button="true"]').live('click', function (e) {
    var form = $(this).parents('form');
    var icon = form.find('[data-app-form-submitting-icon="true"]');
    icon.show();
    $(this).attr('disabled', 'disabled');
    $.ajaxSetup({ async: false });
    var isValid = form.valid();
    $.ajaxSetup({ async: true });
    alert(isValid);
});
Run Code Online (Sandbox Code Playgroud)

问题是,ajax设置调用并没有真正关闭异步.如果我将它移出click函数,但它会禁用所有内容的异步.相反,页面立即警告"true",通过在远程验证操作方法上设置断点进行测试.

有任何想法吗?

附加说明:

我忘了提一下,在IE8中,当有问题的文本框未能在客户端上进行验证时,才会触发提交事件.例如,如果它不需要或正则表达式,则触发submit().对于远程验证操作方法,不会触发它.但是,一旦客户端验证失败,后续远程验证也会触发IE8提交事​​件.

对Russ Cam的回应(评论#1)

以下是viewmodel中的相关代码:

public class SignUpForm : IValidatableObject
{
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Email Address")]
    [Required(ErrorMessage = "Email Address is required.")]
    [RegularExpression(@"^(email regex here)$",
        ErrorMessage = "This is not a valid email address.")]
    [Remote("Validate", "ControllerName", "AreaName", HttpMethod = "POST")]
    public string EmailAddress { get; set; }

    public IEnumerable<ValidationResult> Validate(
        ValidationContext validationContext)
    {
Run Code Online (Sandbox Code Playgroud)

我很高兴你让我看看渲染<form>.表单标记和输入元素如下所示:

<form action="/post-action-method" method="post" novalidate="novalidate">
...
<input class="text-box single-line" data-app-focus="true" data-val="true" 
    data-val-regex="This is not a valid email address." 
    data-val-regex-pattern="^(email regex here)$" 
    data-val-remote="&amp;#39;Email Address&amp;#39; is invalid." 
    data-val-remote-additionalfields="*.EmailAddress" 
    data-val-remote-type="POST" 
    data-val-remote-url="/validate-action-method" 
    data-val-required="Email Address is required." 
    id="EmailAddress" name="EmailAddress" type="text" value=""> 
 ... 
<input type="submit" value="Submit this form" 
    data-app-form-submit-button="true" />
Run Code Online (Sandbox Code Playgroud)

到目前为止,我从未见过novalidate ="novalidate"属性.以下是cshtml文件中的内容:

@using (Html.BeginForm())
{
    @Html.EditorForModel()
    @Html.AntiForgeryToken("assault")
}
Run Code Online (Sandbox Code Playgroud)

我也使用防伪令牌,如果这有所作为.谢谢.

cou*_*ben 3

这有点老套,但我建议尝试以下方法。

首先,使用 隐藏提交按钮display="none",并显示您自己的“提交”按钮,该按钮运行上面的脚本。

其次,在您的页面中,添加一个标志 var [ var remotePending = false;] 和一个用于setInterval调用的变量 [ var intervalPending;],然后在您的脚本中,将该标志设置为 true,然后使用以下函数调用intervalPending = setInterval('remoteCheck()', 200);

function remoteCheck() {
    if ($.validator.pendingRequest == 0) {
        // requests are done
        // clear interval
        clearInterval(intervalPending);
        // re-enable our "submit" button

        // "click" the hidden button
        $("#hiddenSubmit").click();
    }
    // we will try again after the interval passes
}
Run Code Online (Sandbox Code Playgroud)

这将允许您等待挂起的远程验证完成,然后正常继续。我还没有测试过,所以你可能需要尝试一下才能按你想要的方式工作。