2014-10-19 92 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