2013-03-23 254 views
1

我有兩個類:MVC4 - 結合嵌套集合

public class Exercise 
{ 
    public Guid Id {get;set;} 
    public string Name {get;set;} 
    public List<ExerciseItem> Items {get;set;} 
} 

public class ExerciseItem 
{ 
    public Guid Id {get;set;} 
    public string Name {get;set;} 
    public string Content {get;set;} 
} 

我也有我爲創建運動對象視圖。在該視圖上有一個名爲「Add exercise item」的按鈕,我在其中動態調用ajax方法來爲ExerciseItem對象返回部分視圖。視圖正確返回。這種觀點如下:

@model Elang.Models.ExerciseItem 
<div> 
    <input type="hidden" name="Items.Index" value="@Model.Id" /> 
    <input type="hidden" id="[email protected](Model.Id)__Id" name="Items[@Model.Id].Id" value="@Model.Id" /> 
    <input type="text" id="[email protected](Model.Id)__Content" name="Items[@Model.Id].Content" class="inputText"/> 
</div> 

的問題是,當我提交表單並調用我的「創建」的方法:

[HttpPost] 
public ActionResult Create(Exercise exercise) 
{ 
    //add exercise to db 
    //HOWEVER!! 
    //exercise.Items is empty 
} 

我的項目是空的。我究竟做錯了什麼?有人能給我一些建議,我應該怎麼做才能解決這個問題?

回答

6

我真的不知道爲什麼這麼多人堅持不使用幫助器方法,並且想自己做所有的表單字段。只要你正確地使用它們,助手會確保你的格式是正確的。

但是,您真正的問題在於您的ActionMethod需要的運動模型與PartialView使用的ExerciseItem模型之間的阻抗不匹配。您將Partial用作EditorTemplate,這會導致問題。

取而代之,使用EditorTemplate,並使用幫助器方法,並且一切都將正確工作。

在視圖路徑(本地文件夾或共享視圖)中創建一個名爲EditorTemplates的文件夾並添加一個名爲ExerciseItem.cshtml的文件。在該文件中,使用此代碼:

@model Elang.Models.ExerciseItem 
<div> 
    @Html.Hidden(m => m.Id) 
    @Html.TextBoxFor(m => m.Content) 
</div> 

然後,在你的父視圖,只需使用下面,它會在所有集合自動迭代,併產生正確命名的字段:

@Html.EditorFor(m => m.Items) 

如果您仍然希望使用Ajax檢索項目,然後將EditorFor放入部分視圖中,並使局部視圖採用練習模型。

簡單地說,當渲染集合時,使用USE Editor/Display Tempates。它會讓你的生活變得如此簡單,並且可以防止讓你的表單字段命名約定以模型聯編程序所期望的正確格式出現。

我認爲這裏關於「我的模型是空的!」的至少50%的問題!品種不會發生,如果他們正確使用EditorTemplates

+0

使用上述EditorFor方法收集有一個缺點,我已經注意到了。想象一下,你想要列出你的項目,如:1. Item1 2. Item2,3.Item3。因此,你如何實現某種可用於計算物品的索引器? – 2013-09-23 11:34:03

+0

@PiotrPtak - 有很多方法可以解決這個問題,我個人會簡單地確定索引號在模型中。如果你不能這樣做,那麼你仍然可以在for循環(不是foreach)或者其他六種方法中使用EditorFor。 – 2013-09-23 13:30:14