2013-05-26 32 views
0

我想將視圖綁定到我的自定義模型的集合。這應該是沒有任何問題,如果我去的generel辦法做到這一點,通過從我的觀點的模型項循環,並用括號語法,說明模型時:MVC和數據綁定到模型的子選擇

即:

@Html.HiddenFor(m => Model[i].Id) 

我的問題是,我需要做的我的模型項目的一些分組,因此我做了我的項子選擇:

@foreach(var itemType in Model.GroupBy(item => item.Type).Select(grp => grp.First())) 
{ 
    <p>@itemType:</p> 

    var selection = Model 
     .Where(p => p.Type == itemType) 
     .OrderBy(p => p.CreationDate); 

    for (int i = 0; i < selection.Count(); i++) { 
     @Html.HiddenFor(m => selection[i].Id) 
     @* all my other element bindings here... *@ 
     ... 
    } 

現在的問題是,我的控制方法,接收提交的表單,得到一個空的模型。所以模型的序列化在某個時候被打破了;也許MVC不喜歡我的「選擇」變量名稱?或者我的問題可能是什麼,我怎麼能解決它?

+0

什麼視圖模型看起來像你想綁定到(在接收提交的控制器方法中)?它只是一個集合,你只是試圖返回原始集合的一個子集? – CorrugatedAir

+0

我的視圖模型只是一個簡單的POCO類的集合。然後我的視圖可以編輯集合中的項目。所以,我不想減少原始收藏。子集「選擇」僅用於迭代我的集合中每個組的子集項。 –

+0

我對這些物品的命名更感興趣,但我可能已經有足夠的空間去這裏了 – CorrugatedAir

回答

1

問題出現在生成視圖時爲每個項目生成的名稱。模型聯編程序使用名稱 - 值對來計算如何將表單值映射到您期望的視圖模型中控制器。

當你使用@Html.HiddenFor(m=>m[i].Id),那是個好人,會產生在你的HTML下面的名稱屬性:

name="[0].ModelId" 

以後的人會

name="[5].ModelId" 

等等。

這裏是被你的看法產生什麼樣的HTML:

HTML source of view

有兩個問題在這裏:

  1. 「選擇」出現在名字前面的值
  2. 這是使用兩次數組索引

這是因爲所有HTML標籤在最後工作的方式(HiddenFor,TextboxFor等)。他們根據lambda表達式確定name屬性 - 因爲您在第一個中使用的是m => m[0].ModelId,所以它使用[0].ModelId作爲名稱。在第二個,你用m=> selection[0].ModelId,於是就用selection[i].ModelId(它消除你作爲你的拉姆達的一部分,任何變量。

那麼,你如何解決這個問題?

您可以通過以下兩種方法之一來解決這在給定當前設置的情況下,你可以在循環外部使用一個計數器並將其用作數組索引,或者你可以利用額外的隱藏字段作爲索引字段。對於任何一種方法,你都必須放棄強類型的HiddenFor/TextBoxFor並使用Hidden/TextBox來代替,因此您可以手動設置正在生成的HTML元素的名稱。

與索引字段會發生什麼事是你有你的項目名稱爲類似如下:

<input type="hidden" name="Index" value="Model1"/> 
<input type="hidden" name="[Model1].ModelId" value="1"/> 
<input type="hidden" name="[Model1].ModelValue" value="Some value"/> 

在第一次輸入的標籤,我把它叫做索引並設置一些值將作爲該指數這個相關的一組值。在剩餘的那些上,我使用第一個值中的值作爲數組索引,然後是該屬性的名稱。如果您處於從列表中添加/刪除項目的情況,並且無法保證在回發時依次包含所有數字,則此方法尤其有用。

因此,這是你的剃鬚刀的代碼可能是什麼樣子:

for (int i = 0; i < selection.Count(); i++) { 
    @Html.Hidden("Index", "Model"+selection[i].ModelId) 
    @Html.Hidden("[Model"+selection[i].ModelId + "].ModelId", selection[i].ModelId) 
    @Html.Hidden("[Model"+selection[i].ModelId + "].CreateDate", selection[i].CreateDate) 
    @Html.Hidden("[Model"+selection[i].ModelId + "].ModelValue", selection[i].ModelValue) 

一點題外話,我選擇了包括單詞「模型」作爲索引的一部分,所以這樣它肯定知道,它指的是它作爲一個字典式的入口而不是數組中的數字位置。我不知道你是否絕對需要這樣做,我其實沒有嘗試過其他方式。我使用ModelId作爲索引值,因爲它應該是唯一的值。

最終的結果是,你應該已經生成的HTML看起來像這樣(在名稱方面的屬性):

enter image description here

希望幫助!