我的MVC应用程序有一个经典的父子(主 – 细)关系.
我想在同一页面上创建一个单一的页面来创建新的父项和子项.我添加了一个动作,返回部分视图,并将子HTML添加到父视图中,但是我不知道如何将动作中新创建的子对象与原始父项关联(换句话说,我如何添加新的子实体在父实体中收集这些实体).
我猜,当我提交表单时,动作应该在父集合中收集新创建的子节点.
所以为了使事情变短,创建子实体的操作代码应该是什么,以及孩子如何添加到其父集合?
我已经阅读了很多帖子(和其他网站),找不到一个例子.
该应用程序使用MVC 4和实体框架5.
代码示例(我删除了一些代码保持简单).
该模型是Form(Parent)和FormField(child)实体.
public partial class Form { public int ID { get; set; } public string Name { get; set; } public virtual ICollection<FormField> FormFields { get; set; } } public partial class FormField { public int ID { get; set; } public string Name { get; set; } public int FormID { get; set; } }
以下部分视图(_CreateFormField.cshtml)创建新的FormField(子).
@model FormField @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>FormField</legend> <div class="editor-label"> @Html.LabelFor(model => model.Name) </div> <div class="editor-field"> @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name) </div> <div class="editor-label"> @Html.LabelFor(model => model.FormID) </div> <div class="editor-field"> @Html.EditorFor(model => model.FormID) @Html.ValidationMessageFor(model => model.FormID) </div> </fieldset> }
并且以下视图(Create.cshtml)是创建窗体的视图.
@model Form @using (Html.BeginForm()) { @Html.ValidationSummary(true) <fieldset> <legend>Form</legend> <div class="editor-label"> @Html.LabelFor(model => model.Name) </div> <div class="editor-field"> @Html.EditorFor(model => model.Name) @Html.ValidationMessageFor(model => model.Name) </div> <div> @Html.ActionLink( "Add Field","CreateFormField",new { id = -1},new { @class = "form-field" }) </div> <p> <input type="submit" value="Create" /> </p> </fieldset> } <div> @Html.ActionLink("Back to List","Index") </div> <div id="CreateFormField"></div> @section Scripts { <script> $(function () { $('.form-field').on('click',function (e) { $.get($(this).prop('href'),function (response) { $('#CreateFormField').append(response) }); e.preventDefault(); }); }); </script> @Scripts.Render("~/bundles/jqueryval") }
以下操作处理FormController中的创建.
[HttpPost] public ActionResult Create(Form form) { if (ModelState.IsValid) { db.Forms.Add(form); db.SaveChanges(); return RedirectToAction("Index"); } return View(form); } public ActionResult CreateFormField(string id = null) { // I guess something is missing here. return PartialView("_CreateFormField",new FormField()); }
提前致谢,
沙龙.
解决方法
我认为最好的和最简单的方式是你有一个创建窗体的视图,并在底部放置一个fieldset来分配FormFields.
对于字段集,您应该有两个部分视图:一个用于创建,另一个用于编辑.部分创建视图应该是这样的:
@model myPrj.Models.Form_FormFieldInfo @{ var index = Guid.NewGuid().ToString(); string ln = (string)ViewBag.ListName; string hn = ln + ".Index"; } <tr> <td> <input type="hidden" name="@hn" value="@index" /> @Html.LabelFor(model => model.FormFieldID) </td> <td> @Html.DropDownList(ln + "[" + index + "].FormFieldID",new SelectList(new myPrj.Models.DbContext().FormFields,"ID","FieldName")) </td> <td> <input type="button" onclick="$(this).parent().parent().remove();" value="Remove" /> </td> </tr>
通过在创建位置视图ajaxly中调用此部分视图,可以为每个标签渲染一些元素.每行元素都包含一个标签,一个包含标签的DropDownList和一个删除按钮,以简单地删除所创建的元素.
在创建场景视图中,您有一个裸表,其中包含通过部分视图创建的元素:
<fieldset> <legend>Form and FormFields</legend> @Html.ValidationMessageFor(model => model.FormFields)</label> <table id="tblFields"></table> <input type="button" id="btnAddTag" value="Add new Field"/> <img id="imgSpinnerl" src="~/Images/indicator-blue.gif" style="display:none;" /> </fieldset>
并且您有以下脚本来为每个标签创建一行元素:
$(document).ready(function () { $("#btnAddField").click(function () { $.ajax({ url: "/Controller/GetFormFieldRow/FormFields",type: 'GET',dataType: 'json',success: function (data,textStatus,jqXHR) { $("#tblFields").append(jqXHR.responseText); },error: function (jqXHR,errorThrown) { $("#tblFields").append(jqXHR.responseText); },beforeSend: function () { $("#imgSpinnerl").show(); },complete: function () { $("#imgSpinnerl").hide(); } }); }); });
GetFormFieldRow的动作方法如下所示:
public PartialViewResult GetFormFieldRow(string id = "") { ViewBag.ListName = id; return PartialView("_FormFieldPartial"); }
和您完成的创建…您的问题的整个解决方案有许多视图,部分视图,控制器,ajax调用和模型绑定的代码.我试图只是告诉你的方式,因为我真的不能发布所有这些在这个答案.
希望这个答案是有用的,并为你带来方法.