2014-10-19 68 views
3

ASP.NET MVC 5編輯選項我已要求工作和屬性之一,其目的在於步驟清單:複雜列表兒童

public class Job 
{ 
    [Display(Name = "Id")] 
    public int? JobId { get; set; } 

    [Required] 
    public string Name { get; set; } 

    public List<Step> Steps { get; set; } 

    public Job() 
    { 
     Steps = new List<Step>(); 
    } 
} 

public class Step 
{ 
    public int? StepId { get; set; } 

    public int JobId { get; set; } 

    [Required] 
    public string Name { get; set; } 
} 

我有一個JobController與下面的操作來執行更新:

// PUT: /Job/Edit/5 
    [HttpPut] 
    public ActionResult Edit(Job model) 
    { 
    // Logic to update model here 
    } 

一種基於這個問題的答案question我我的UI(使用附帶MVC5的引導模板)更新爲:

@using (Html.BeginForm()) 
{ 
    @Html.HttpMethodOverride(HttpVerbs.Put) 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     @Html.HiddenFor(model => model.JobId) 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 

      <div class="col-md-10"> 
       @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <h3>Steps</h3> 
     <div> 
      @foreach (var item in Model.Steps) 
      { 
       <div class="form-group"> 
        @Html.Hidden("Steps[" + stepIndex + "].StepId", item.StepId) 
        @Html.LabelFor(modelItem => item.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 

        <div class="col-md-10"> 
         <input class="form-control text-box single-line" data-val="true" data-val-required="The Name field is required." 
           id="@String.Format("Steps_{0}__Name", stepIndex)" name="@String.Format("Steps[{0}].Name", stepIndex)" type="text" value="@item.Name" /> 

        @Html.ValidationMessageFor(modelItem => item.Name, "", new { @class = "text-danger" }) 
        </div> 
       </div> 
       stepIndex += 1; 
       <hr /> 
      } 
     </div> 
     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
        <input type="submit" value="Save" class="btn btn-default" /> 
       </div> 
      </div> 
     </div> 
} 

正如你所看到的,我必須手動構建與使用Html.EditorFor相反的輸入標籤。原因是我需要控制ID的名稱,以便它將索引傳入ID和名稱。我會假設有一個更好的方法可以讓MVC使用labelFor,EditorFor和ValidationMessageFor來呈現正確的值。

我的問題是:

  1. 是否有一組控件我可以MVC5使用,讓我來渲染複雜的子對象,而通過這些額外的步驟去?
  2. 如果沒有1,那麼是否有比手動創建輸入標籤更好的方法?

回答

6

選擇1:for更換foreach循環:

@for (int i = 0; i < Model.Steps.Count; i++) 
{ 
    <div class="form-group"> 
     @Html.HiddenFor(m => m.Steps[i].StepId) 
     @Html.TextBoxFor(m => m.Steps[i].Name, new { @class = "form-control text-box single-line" }) 
     ... 
    </div> 
} 

選項2:爲Step類創建一個名爲Step.chtml編輯模板,並使用EditorFor

Step.chtml

@model Step 
<div class="form-group"> 
    @Html.HiddenFor(m => m.StepId) 
    @Html.TextBoxFor(m => m.Name, new { @class = "form-control text-box single-line" }) 
    ... 
</div> 

主視圖

<h3>Steps</h3> 
<div> 
    @Html.EditorFor(m => m.Steps) 
<div> 

在這兩個方面的框架會給輸入正確的名稱和ID。

2

看起來像複雜的東西,試試下面。
1.使用Step步驟在EditorTemplates文件夾下創建一個名爲'Step.cshtml'的新編輯器模板(這是一個視圖)。
2.在做下面的代碼,
Step.cshtml

@model Step 
<div class="form-group"> 
@Html.HiddenFor(model => model.StepId) 
@Html.LabelFor(modelItem => modelItem.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 

<div class="col-md-10"> 
    @Html.TextBoxFor(model => model.Name, htmlAttributes: new { @class = "form-control text-box single-line" }) 
    @Html.ValidationMessageFor(modelItem => modelItem.Name, "", new { @class = "text-danger" }) 
</div> 

3.從您的視圖中刪除foreach語句,而是調用編輯模板,

@Html.EditorFor(model => model.Steps) 
+0

很好的答案,但Zabavsky比同樣的答案快了一分鐘。 – Josh 2014-10-19 16:38:10

+0

@Josh感謝您的讚賞,我正在嘗試發佈您修改過的視圖的完整源代碼,這在我以代碼格式呈現時並不擅長,這些代碼格式讓我無法回答。無論何人,任何方式的答案都有幫助快樂。 – Venkat 2014-10-19 16:41:25