2011-06-17 74 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如果你需要的特定擴展方法,例如...

相關問題