2012-02-03 50 views
21

我一直被困在很長的時間來編輯我的模型的子集合,模型的集合是空的。Asp:net MVC 3:@ Html.EditorFor模板中的模型子集合?

我終於找到了解決辦法,但我覺得它有點髒:

首先我的測試DATAS:

Model對象

public class ContainerObject 
    { 
     public String Title { get; set; } 
     public List<ContainedObject> ObjectList { get; set; } 
    } 

分集合對象

public class ContainedObject 
{ 
    public int Id { get; set; } 
    public String Text { get; set; } 
    public Boolean IsSelected { get; set; } 
} 

控制器方法,其生成所述對象

public ActionResult TestForm() 
    { 
     return View(new ContainerObject() 
     { 
      Title = "This is a sample title", 
      ObjectList = new List<ContainedObject>() 
       { 
        new ContainedObject(){Id=1, IsSelected = true, Text="ObjectOne"}, 
        new ContainedObject(){Id=2, IsSelected = false, Text="ObjectTwo"}, 
        new ContainedObject(){Id=3, IsSelected = true, Text="ObjectThree"}, 
        new ContainedObject(){Id=4, IsSelected = false, Text="ObjectFour"}, 
       } 
     }); 
    } 

控制器,其接收被編輯的對象

[HttpPost] 
    public ActionResult TestFormResult(ContainerObject filledObject) 
    { 
     return View(); 
    } 

視圖

@model WebTestApplication.Models.ContainerObject 

@{ 
    ViewBag.Title = "TestForm"; 
} 
@using (Html.BeginForm("TestFormResult","Home", FormMethod.Post)){ 
    @Html.EditorFor(x => x.Title) 
    Html.RenderPartial("ContainedObject", Model.ObjectList); 
    <input type="submit" value="Submit"/> 
} 

局部v IEW(ContainedObject.cshtml)

@model IEnumerable<WebTestApplication.Models.ContainedObject> 
@{ 
    ViewBag.Title = "ContainedObject"; 
    int i = 0; 
} 
@foreach (WebTestApplication.Models.ContainedObject currentObject in Model) 
{ 
    <br /> 
    @Html.Label(currentObject.Text); 
    @Html.CheckBox("ObjectList[" + i + "].IsSelected", currentObject.IsSelected);                          
    @Html.Hidden("ObjectList[" + i + "].Id", currentObject.Id);                         
    @Html.Hidden("ObjectList[" + i + "].Text", currentObject.Text); 
    i++; 
} 

這實際上是工作,但我有一個問題:

  • 我已經生成自己的名字,並指定容器對象的屬性

我試圖使用Html.EditorFor而不是Html.RenderPartial在視圖中,問題是它生成我的名字「ObjectList。[0] .Id」(附加一個。屬性名稱和訪問者之間)。

我也嘗試在部分視圖中僅使用@ Html.EditorFor,但它創建了具有對象名稱的變量。

如果我不使用任何模板,它的工作原理:

@model WebTestApplication.Models.ContainerObject 

@{ 
    ViewBag.Title = "TestForm"; 
} 
@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post)) 
{ 
    @Html.EditorFor(x => x.Title) 
    for (int i = 0; i < Model.ObjectList.Count; i++) 
    { 
     <br /> 
     @Html.Label(Model.ObjectList[i].Text); 
     @Html.CheckBoxFor(m => Model.ObjectList[i].IsSelected); 
     @Html.HiddenFor(m => Model.ObjectList[i].Id); 
     @Html.HiddenFor(m => Model.ObjectList[i].Text); 
    } 

    <br /><input type="submit" value="Submit"/> 
} 

但在這裏它是一個簡單的模板,但是在我的實際情況,我將有更多的數據,這將被重新使用多次。那麼我最好的選擇是什麼?

回答

38

您可以通過引入EditorTemplate來簡化代碼。這裏是如何:

  • 主視圖保持幾乎相同,除了我們用EditorFor取代的RenderPartial:

TESTFORM。CSHTML

@model WebTestApplication.Models.ContainerObject 

@{ 
    ViewBag.Title = "TestForm"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

@using (Html.BeginForm("TestFormResult", "Home", FormMethod.Post)) { 
    @Html.EditorFor(m => m.Title) 
    @Html.EditorFor(m => m.ObjectList); 

    <input type="submit" value="Submit" /> 
} 
  • 然後創建一個名爲EditorTemplates查看/首頁文件夾中(假設你的控制器主頁):

enter image description here

  • ,並添加以下ContainedObj的模板ECT

ContainedObject.cshtml

@model WebTestApplication.Models.ContainedObject 

<p> 
    @Html.DisplayFor(m => m.Text) 
    @Html.CheckBoxFor(m => m.IsSelected) 
    @Html.HiddenFor(m => m.Id) 
    @Html.HiddenFor(m => m.Text) 
</p> 

,編輯器會自動通過的物體渲染爲他們每個人的觀點的列表進行迭代。希望能幫助到你。

+1

驚人!我不知道如果它是一個列表,editorFor或DisplayFor會自動迭代!有沒有辦法讓它在指定它必須使用的模板時工作? – J4N 2012-02-06 11:44:05

+0

因爲事實上,我有幾次可以用複選框(多選)或無線電按鈕(一個項目選擇)顯示一些信息,在同一個控制器(例如選擇值和默認值) – J4N 2012-02-06 13:50:41

+0

你想指定不同的模板?如果是這樣,那麼EditorFor的接受模板名稱會出現重載。 – 2012-02-06 16:53:43

5

我在查找其他相關內容時發現此線程。丹尼斯有正確的答案,但我想我會添加一些語法,以防其他人遇到這種情況:

如果您有一個名爲「SomeTemplate.cshtml」的編輯器模板,您可以將它用於如下所示的Item列表您的看法:

@for (var i = 0; i < Model.ObjectList.Count(); i++) 
{ 
    @Html.EditorFor(m => m.ObjectList[i], "SomeTemplate") 
} 

然後在編輯器中的模板:

@model WebTestApplication.Models.ContainedObject 

<br /> 
@Html.Label(Model.Text); 
@Html.CheckBoxFor(m => m.IsSelected); 
@Html.HiddenFor(m => m.Id); 
@Html.HiddenFor(m => m.Text);