1

我们有一个带有约 400 个输入字段的掩码,这些字段都加载在客户端上。掩码由几个选项卡和手风琴组成,使用户能够直接查看和编辑所有必要的字段。在编辑结束时,在客户端验证掩码。

我们将jQuery UI用于选项卡和手风琴,使用jQuery Validation Plugin进行客户端验证。在我们运行 ASP.NET MVC 的服务器上。为了生成具有必要data-val-*属性的 HTML,我们使用了不同的技术:

  • 默认 EditorFor-helper 函数 ( @Html.EditorFor(model => model.property)
  • 特定的 TextBoxFor、DropDownListFor 辅助函数(`@Html.EditorFor(model => model.property')
  • 自定义 HTML 标签,当我们需要特定格式时,例如:

    <input 
        class="text-box single-line" 
        data-val="true" 
        data-val-number="The field @data.Title must be a number." 
        id="@data.Name" 
        name="@data.Name" 
        type="text" 
        value="@data.Value" @(data.IsDisabled ? "disabled='disabled'" : string.Empty ) />
    

但是我们不使用扩展函数生成的字段看起来都非常相似,例如:

<input name="fieldName" 
       class="text-box single-line valid" 
       id="fieldName" 
       type="text" 
       value="311969d" 
       data-val="true" 
       data-val-length-max="8" 
       data-val-length="The field fieldName must be a string with a maximum length of 8.">

如果我value用超过 8 个字符修改此输入,该字段将标记为红色,显示和错误,并且一切正常。

但是,当我按下提交时,验证需要大约 12.5 秒 - 这是我从 IE 得到的 - 分析器:

执行的一轮验证的 IE-profiler 屏幕截图

正如我更新这个问题之前的评论中提到的那样,DOM Manipulations 使执行变得非常缓慢,但我不明白为什么 jQuery-Validation 插件会向我的 HTML 页面添加新元素。在这里您可以看到showLabel执行 DOM 操作的 -function:

showLabel: function(element, message) {
    var label = this.errorsFor( element );
    if ( label.length ) {
        // refresh error/success class
        label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );

        // check if we have a generated label, replace the message then
        label.attr("generated") && label.html(message);
    } else {
        // create label
        label = $("<" + this.settings.errorElement + "/>")
            .attr({"for":  this.idOrName(element), generated: true})
            .addClass(this.settings.errorClass)
            .html(message || "");
        if ( this.settings.wrapper ) {
            // make sure the element is visible, even in IE
            // actually showing the wrapped element is handled elsewhere
            label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
        }
        if ( !this.labelContainer.append(label).length )
            this.settings.errorPlacement
                ? this.settings.errorPlacement(label, $(element) )
                : label.insertAfter(element);
    }
    if ( !message && this.settings.success ) {
        label.text("");
        typeof this.settings.success == "string"
            ? label.addClass( this.settings.success )
            : this.settings.success( label );
    }
    this.toShow = this.toShow.add(label);
},

然而有趣的是,现在错误标签或任何类似的东西都会显示出来,或者出现在 DOM 上。此外,我们实际上不希望显示任何标签,因为掩码上没有任何空间。我们宁愿使用显示错误的工具提示文本,因为它适用于大多数现代浏览器和 HTML 5 验证。

对于短期解决方案,如果我们能以某种方式禁用(仅针对此掩码)DOM 操作会很好。是否有可能通过一些配置?

更复杂的解决方案是使用 HTML 5 验证而不是 JavaScript,因为我们的客户现在已经使用 IE 9 或 10,如果需要,他们将能够升级到支持它的 10。我从去年 11 月发现了一个关于它的 SO 问题:ASP.NET MVC 5 and HTML 5 form attributes based on the W3C specs - 也许某些东西已经改变或将以这种方式改变?由于所有领域的手动实施将是太多的工作。

4

2 回答 2

0

我会一次验证一个字段集。

每次用户打开一个窗格然后在该窗格上的字段中输入一些数据时,该窗格将被标记为“脏”。现在,当用户继续打开另一个窗格时,他将无法“离开”,直到他修复了对当前窗格上的字段提出的任何验证要求。

这样,验证将发生在离散的部分,避免不必要的往返于用户甚至没有触及的字段。

于 2014-04-01T15:39:22.977 回答
0

您需要支持哪些浏览器?对于较新的浏览器,您可以使用HTML5 表单验证,例如:

<form>
  <label for="choose">Would you prefer a banana or a cherry?</label>
  <input id="choose" name="i_like" pattern="banana|cherry">
  <button>Submit</button>
</form>

作为旧浏览器的后备,您可以包含验证脚本。

于 2014-04-01T15:06:40.487 回答