2016-04-25 24 views
1

我使用的是MVC 5,我想要一個編輯頁面,允許從列表中選擇項目,併爲每個項目選擇選項。所以我有這樣一個模型:如何在MVC中處理嵌套集合5

public class TemplateEdit 
{ 
    public Guid TemplateId {get; set;} 
    public string TemplateName {get; set;} 
    public ICollection<MyOption> Options {get; set;} 
} 

public class MyOption 
{ 
    public Guid MyOptionId {get; set;} 
    public Guid TemplateId {get; set;} 
    public string OptionName {get; set;} 
    public bool Selected {get; set;} 
    public ICollection<SubOption> SubOptions {get; set;} 
} 

public class SubOption 
{ 
    public Guid SubOptionId {get; set;} 
    public Guid MyOptionId {get; set;} 
    public string SubOptionName {get; set;} 
    public bool Selected {get; set;} 
} 

我們假設我有LINQ來獲取這個數據。現在我想要顯示它。我曾希望使用Editor模板。

在我template-edit.cshtml鑑於我有這樣的事情:

@model TemplateEdit 
<div class="form-group col-md-12"> 
    @Html.ValidationSummary(false, "", new { @class = "text-danger" }) 
    @Html.HiddenFor(model => model.TemplateId) 
</div> 

<div class="form-group col-md-12"> 
    @Html.LabelForRequired(m => m.TemplateName, new {@class = "control-label"}) 
    @Html.TextBoxFor(m => m.TemplateName, new {@class = "form-control"}) 
</div> 

<div class="col-md-12" style="overflow: auto; height: 350px;"> 
    @Html.Label("Options Selected") 
    <div> 
     @Html.EditorFor(m => m.Options); 
    </div> 
</div> 

MyOption.cshtml EditorTemplate:

@model MyOption 
<div class="optionable"> 

    @Html.HiddenFor(m => m.MyOptionId) 
    @Html.HiddenFor(m => m.TemplateId) 

    <div class="row"> 
     <div class="col-md-2"> 
      @Html.CheckBoxFor(model => model.Selected, new { @class = "form-control optionToggle" }) 
     </div> 

     <div class="col-md-8"> 
      @Html.DisplayFor(model => model.OptionName, new { @class = "form-control" }) 
     </div> 
    </div> 
    <div class="row options"> 
     @Html.EditorFor(m => m.SubOptions); 
    </div> 
</div> 

在我SubOption.cshtml EditorTemplate:

@model SubOption 
<div class="optionable"> 

    @Html.HiddenFor(m => m.SubOptionId) 
    @Html.HiddenFor(m => m.MyOptionId) 

    <div class="row"> 
     <div class="col-md-2"> 
      @Html.CheckBoxFor(model => model.Selected, new { @class = "form-control optionToggle" }) 
     </div> 

     <div class="col-md-8"> 
      @Html.DisplayFor(model => model.SubOptionName, new { @class = "form-control" }) 
     </div> 
    </div> 
</div> 

我遇到的問題是當我返回模型時,我就是沒有得到SubOption數據。

注:
所有我找到的例子是MVC3或更早版本,並使用索引方法通過收集迭代。我會嘗試,除了我使用ICollection的集合。

+0

選項是否正確返回,但SubOptions不正確?此外,你可以分享什麼@ Html.HiddenFor(m => m.SubOptionId)實際上是在頁面上呈現? EditorTemplates應該在這裏工作,只要正確的名字在頁面上呈現 –

+0

你根本沒有得到任何數據,或者你只是缺少'OptionName'和'SubOptionName'屬性?當我嘗試這些時,只有那些人失蹤了,這是有道理的,因爲他們沒有'HiddenFor'。 –

+0

您顯示的代碼將正常工作。 POST方法的簽名是什麼 –

回答

2

檢查您的操作在您的控制器中的樣子。如果你傳遞viewmodel作爲參數,它應該包含你的'SubOptions'集合。

[HttpPost] 
    public ActionResult SaveData(MyViewModel model) 
    { 
    } 
+0

_人們請不要爲我拒絕我。爲什麼不呢?你知道規則。但你可能只是做出了這個答案。 – Mogsdad

+0

還不確定,如果這解決了OP的請求,所以我不想發佈它作爲答案。感謝您爲我編輯我的答案。 –

-1

更改SubOption.cshtml看起來像這樣:

@model System.Collections.Generic.IEnumerable<SubOption> 
@foreach(var option in Model) 
{ 
    <div class="optionable"> 

     @Html.HiddenFor(m => option.SubOptionId) 
     ... 

    </div> 
} 

你傳遞一個集合到EditorFor所以你的模板還應該有一個收集工作中的單個項目,而不是。

+1

這實際上沒有必要。當一個集合被傳入EditorFor()時,MVC足夠聰明地爲每個呈現一個EditorTemplate。事實上,當以這種方式循環時,我經常看到模型綁定失敗時,模型發回 –

+1

使用foreach幾乎總是錯誤的解決方案,並不會產生正確的命名。此外,正如洛倫所說,這是沒有必要的。 –

+0

嗯,據我所知,當我積極使用MVC時,這種方法適用於我。它也被認爲是一個工作解決方案:http:// stackoverflow。com/a/20280559/3731444 但是,我不是MVC專業人員,所以我可能仍然是錯的。你能否描述這種方法有什麼問題? –