2011-06-17 60 views
0

我已经编写了一些扩展方法来扩展客户端表单验证的html助手类。我希望能够做的是在页面中加载一个数组(javascript),它是我的验证“库”中的所有元素。在加载mvc3之前解析页面上的所有html助手扩展

例如:

@Html.VTextBox("blah) 
@Html.VDropDownList("bling") 
@Html.VTextBox("bloo") 

加载页面时,我想一个JavaScript阵列放置在充满了这样的事情上:

errorListArr = new Array("blah","bling","bloo"); 

目前我在做什么是对每个元素使用errorListArr.push()并且每次写出脚本标记......显然不是最优雅的方法。我还想弄清楚如何提前解析整个页面,以便我可以将我需要验证服务器端的元素列表放在一起。

请让我知道这是否可以完成,任何代码片段/示例将不胜感激。

+0

几个问题:1:你有没有考虑使用“不显眼的JavaScript“技巧,以避免需要这些脚本片段? 2:为什么数组需要放在页面顶部(而不是底部)? 3:为什么你需要一个你要验证的元素(客户端)列表(服务器端)? – StriplingWarrior 2011-06-17 04:05:06

+0

1.不确定你在这里的意思2.数组可能在底部,这将是好3.基本上我试图使这个代码尽可能重用,而不必编写一堆更多的代码服务器端。所以看上面我的例子,我简单地放入一个@ Html.VTextBox客户端和服务器端应该知道它需要验证。 VTextBox元素采用“类型”参数,如电子邮件的“e”或电话的“p”。我想要做的是传递一个隐藏的表单变量与所有需要验证服务器端的元素。我不能把我听到的关于创建列表4 arr也听到。 – 2011-06-17 04:17:48

回答

1

我并不完全清楚你想要做什么,但我认为我足够理解,指出你在正确的方向。

首先,MVC 3中的服务器端验证通常是作为回传到采用模型并验证它的动作来完成的。如果模型无效,则使用(现在验证的)模型返回视图,并且该视图将为错误的属性呈现适当的错误消息。

默认情况下,您可以通过将某些属性添加到要渲染输入的模型的属性来定义要执行的验证。

更重要的是,当用户尝试提交表单时,MVC足够智能地输出客户端JavaScript来执行其中的许多验证,而根本不需要回发!

请参阅this post了解如何使用模型验证。

在MVC 3中,您也可以选择启用"unobtrusive javascript" validation,它基本上和平时一样进行客户端验证,但不是生成一堆内联javascript,而是使用某些“数据 - “属性。几个基于jquery的库然后扫描页面查找带有这些标志的元素,并为它们添加适当的验证处理程序。

如果您的验证需求超出了MVC提供的验证需求,那么添加您自己的验证属性或者甚至让您的模型执行自定义逻辑来验证自己是很容易的。

一般来说,如果你发现你的渲染了很多小的JavaScript片段客户端,你可能要遵循“不显眼的JavaScript”自己的模式:在静态的JavaScript

  1. 将代码该文件知道如何扫描DOM中感兴趣的特定标志。
  2. 使用“data-”属性在必要时使用“data-”属性添加细节来渲染添加了这些标志的HTML元素。
0

你的“验证库”可能不包含这么多的扩展方法。因此,在每个代码中放入相同的代码行以将处理后的元素的名称添加到数组中并不那么不雅。

另一种方法是人为地将所有元素都通过验证,这要归功于您的“验证库”:一个通用的标记接口。这个想法是:不要使用这些元素作为它们真实类型的实例。取而代之的是这些类型的子类型,它们也实现了接口IValidated,只有一个string ID成员(我想这里所有你感兴趣的元素已经拥有这样的属性,这要归功于它们是原始类的原始类)。然后,一旦完成了所有需要的操作,在将页面发送到客户端之前,只需将一次数组构建为结束操作即可。现在,您的所有自定义验证要素识别由于IValidated,这是用一行代码这样很容易:

errorListArr = new Array(this.Page.SubControls().OfType<IValidated>().Select(elt => elt.ID)); 

SubControls是一个非常方便的扩展方法来获取所有的子控件无论他们在控制深度树:

public static IEnumerable<Control> Subcontrols<T>(this T parentControl) where T : Control 
{ 
    //Recursively returns all the parentContol's descendant controls 
    foreach (Control ctrl in parentControl.Controls) 
    { 
     yield return ctrl; 
     foreach (Control childCtrl in ctrl.Subcontrols()) 
     { 
      yield return childCtrl; 
     } 
    } 
} 

当然,你可能需要做一些适应,以达到你的确切需求,但这是主要的想法。

第二个选项的主要优点是给所有元素“共同点”,尽管它们都是各种类别的实例,否则这些实例可能很少有共同点。你创建一个新的功能抽象,这是特定于你的项目,后来你将能够扩展IValidated如果你需要的特定扩展方法,例如...