2015-04-07 131 views
1

我正在使用局部視圖來創建父視圖。我最喜歡的是父視圖上的提交按鈕來保存子值。asp.net mvc父視圖父視圖更新子視圖

我有以下模型。

public class Course 
{ 
    public int CourseId { get; set; } 
    public string Name { get; set; } 
    public int Par { get; set; } 
    public string Tee { get; set; } 
    public decimal Rating { get; set; } 
    public virtual IEnumerable<CourseHole> Holes { get; set; } 

    public static Course Create() 
    { 
     var course = new Course(); 
     course.Par = 72; 
     var holes = new List<CourseHole>(); 
     for (int i = 0; i < 18; i++) 
     { 
      holes.Add(new CourseHole() { Course = course, Number = i + 1, Par = 4 }); 
     } 
     course.Holes = holes; 
     return course; 
    } 
} 

public class CourseHole 
{ 
    public int CourseHoleId { get; set; } 
    public int Number { get; set; } 
    public int Par { get; set; } 
    public int Length { get; set; } 
    public int Ranking { get; set; } 
    public Course Course { get; set; } 
} 

和下面的父視圖。

@model Golf_Statz.Models.Course 

@{ 
    ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 


@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <h4>Course</h4> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     <div class="form-group"> 
      @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-4"> 
       @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) 
      </div> 

      @Html.LabelFor(model => model.Par, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-4"> 
       @Html.EditorFor(model => model.Par, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Par, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.Tee, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-4"> 
       @Html.EditorFor(model => model.Tee, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Tee, "", new { @class = "text-danger" }) 
      </div> 

      @Html.LabelFor(model => model.Rating, htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-4"> 
       @Html.EditorFor(model => model.Rating, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Rating, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     @foreach (Golf_Statz.Models.CourseHole hole in Model.Holes) 
     { 
      @Html.Partial("CreateHole", hole) 
     } 

     <div class="form-group"> 
      <div class="col-md-offset-2 col-md-10"> 
       <input type="submit" value="Create" class="btn btn-default" /> 
      </div> 
     </div> 
    </div> 
} 



<div> 
    @Html.ActionLink("Back to List", "Index") 
</div> 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

以下是部分視圖。

@model Golf_Statz.Models.CourseHole 

@{ 
    ViewBag.Title = "CreateHole"; 
} 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal" id="CreateHole-" + model.CourseHoleId> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     <div class="form-group"> 
      <div class="col-md-2 col-md-offset-2"> 
       <p>@Model.Number</p> 
      </div> 
      <div class="col-md-2"> 
       @Html.EditorFor(model => model.Par, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Par, "", new { @class = "text-danger" }) 
      </div> 
      <div class="col-md-2"> 
       @Html.EditorFor(model => model.Length, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Length, "", new { @class = "text-danger" }) 
      </div> 
      <div class="col-md-2"> 
       @Html.EditorFor(model => model.Ranking, new { htmlAttributes = new { @class = "form-control" } }) 
       @Html.ValidationMessageFor(model => model.Ranking, "", new { @class = "text-danger" }) 
      </div> 
     </div> 
    </div> 
} 

@section Scripts { 
    @Scripts.Render("~/bundles/jqueryval") 
} 

我的控制器方法是。

// GET: Course/Create 
     public ActionResult Create() 
     {   
      return View(Course.Create()); 
     } 

     // POST: Course/Create 
     // To protect from overposting attacks, please enable the specific properties you want to bind to, for 
     // more details see http://go.microsoft.com/fwlink/?LinkId=317598. 
     [HttpPost] 
     [ValidateAntiForgeryToken] 
     public ActionResult Create([Bind(Include = "CourseId,Name,Par,Tee,Rating")] Course course) 
     { 
      if (ModelState.IsValid) 
      { 
       db.Courses.Add(course); 
       foreach (var hole in course.Holes) 
       { 
        db.CourseHoles.Add(hole); 
       } 
       db.SaveChanges(); 
       return RedirectToAction("Index"); 
      } 

      return View(course); 
     } 

無論我看起來做什麼當然HttpPost創建方法中的洞始終爲空。 我想我想要的東西類似於this但它是用於編輯,我希望它用於創建。 任何幫助將不勝感激,因爲這是我的第一個mvc項目。

+0

一些觀察刪除@using (Html.BeginForm()) {}: - 你不能嵌套形式:您的部分有一個表格,我們的父巢這部分每個'CourseHole'。這是不允許的。 - 你部分有一個防僞標記。這是不需要的,因爲父視圖已經有了這個標記。 – Hintham

回答

5

foreach循環產生重複id屬性(無效的HTML),並具有與你的模型沒有關係name屬性。改變局部到EditorTemplate

/Views/Shared/EditorTemplates/CourseHole.cshtml

並取出BeginFormAntiForgeryToken和腳本

@model Golf_Statz.Models.CourseHole 
<div class="form-horizontal" id="CreateHole-" + model.CourseHoleId> 
    <div class="form-group"> 
     <div class="col-md-2 col-md-offset-2"> 
      <p>@Model.Number</p> 
     </div> 
     <div class="col-md-2"> 
      @Html.EditorFor(model => model.Par, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Par, "", new { @class = "text-danger" }) 
     </div> 
     <div class="col-md-2"> 
      @Html.EditorFor(model => model.Length, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Length, "", new { @class = "text-danger" }) 
     </div> 
     <div class="col-md-2"> 
      @Html.EditorFor(model => model.Ranking, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.Ranking, "", new { @class = "text-danger" }) 
     </div> 
    </div> 
</div> 

,然後在主視圖

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

EditorFor()方法將正確地生成綁定到集合的html,例如Ë

<input name="Holes[0].Par" ...> 
<input name="Holes[1].Par" ...> 

你也需要,因爲你是不包括物業Holes去除[Bind]屬性,你似乎要綁定的所有屬性呢。

備註:您不會生成孔CourseHoleIdNumber屬性的輸入,因此這些不會回傳。

+0

你會如何添加一個額外的洞? (我知道這有點超出了OP的功能目標,但我真的很喜歡這種模式,並希望用它來添加額外的子記錄。) –

+0

@ J-Rome。參考答案[這裏](http:// stackoverflow。com/questions/29161481/post-a-form-array-without-successful/29161796#29161796)and [here](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple數據到控制器/ 28081308#28081308)如果你想創建一個窗體來動態地添加/刪除視圖中的集合項目 –

+0

我只是在搜索並找到同樣的問題的答案!感謝您的貢獻! (而且下次我在搜索時會更加勤奮;) –

0

在你的情況下,你有兩種形式! 剃刀會看到這個

<form> 
    <form> 
    </form> 
</form> 

從局部視圖

相關問題