我正在使用 MVC 和剃须刀。
我已经成功地实现了一种让用户通过单击按钮动态添加更多输入行的方法(使用 AJAX 并关注 Steven Sanderson 的博客)。但我不知道如何将数据保存到用户在这些动态创建的字段中输入的数据库中。
我使用他的助手类,坦率地说,我很难理解。
我的问题是我需要在 POST 创建方法中添加什么。他博客中的代码链接在这里: steven sanderson 的博客
我只需要一个指向正确方向的指针。这是我当前的代码:
新行局部视图:
@model ef_tut.ViewModels.ClaimsViewModel
@using ef_tut.WebUI.Helpers
@using (Html.BeginCollectionItem("claims"))
{
<table class="editorRow">
<tr >
<td>
SubmissionUserID: @Html. EditorFor (o.claim.SubmissionUserID)
</td>
<td>
ClaimID: @Html.EditorFor(o => o.claim.ClaimID)
</td>
<td>
@Html.EditorFor(o => o.claim.ApprovedYN)
</td>
<td>
ClaimID(claimlinetable)@Html.EditorFor(o => o.claimline.ClaimID)
</td>
<td>
ClaimantUserID: @Html.EditorFor(o => o.claimline.ClaimantUserID)
</td>
<td>
Hours: @Html.EditorFor(o => o.claimline.Hours)
</td>
<td>
MileageCost: @Html.EditorFor(o => o.claimline.MileageCost)
</td>
<td>
TravelCost: @Html.EditorFor(o => o.claimline.TravelCost)
</td>
<td>
Hours cost: @Html.EditorFor(o => o.claimline.HoursCost)
</td>
<td>
Total cost: @Html.EditorFor(o => o.claimline.TotalCost)
</td>
<td>
ProxyYN: @Html.EditorFor(o => o.claimline.ProxyClaim)
</td>
<td>
CatID: @Html.EditorFor(o => o.claimline.CatID)
</td>
<td>
SubCatID: @Html.EditorFor(o => o.claimline.SubCatID)
</td>
<td>
<a href="#" class="deleteRow">delete</a>
</td>
</tr></table>
}
Blankeditorrow 方法
public PartialViewResult BlankEditorRow()
{
return PartialView("NewRow", new ClaimsViewModel());
}
我当前创建新数据库记录但所有字段为空的 POST 方法
[HttpPost]
public ActionResult Create(ClaimsViewModel viewModel)
{
if (ModelState.IsValid)
{
db.claims.Add(viewModel.claim);
db.claimlines.Add(viewModel.claimline);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(viewModel);
}
创建视图
@model ef_tut.ViewModels.ClaimsViewModel
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>claim</legend>
<div id="editorRows"></div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
<div>
@Html.ActionLink("Add another...", "BlankEditorRow", null, new { id = "addItem" })
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
jQuery
$("#addItem").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) { $("#editorRows").append(html); }
});
return false;
});
$("a.deleteRow").live("click", function () {
$(this).parents("table.editorRow:first").remove();
return false;
});
史蒂文的助手
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Mvc;
namespace ef_tut.WebUI.Helpers
{
public static class HtmlPrefixScopeExtensions
{
private const string idsToReuseKey = "__htmlPrefixScopeExtensions_IdsToReuse_";
public static IDisposable BeginCollectionItem(this HtmlHelper html, string collectionName)
{
var idsToReuse = GetIdsToReuse(html.ViewContext.HttpContext, collectionName);
string itemIndex = idsToReuse.Count > 0 ? idsToReuse.Dequeue() : Guid.NewGuid().ToString();
html.ViewContext.Writer.WriteLine(string.Format("<input type=\"hidden\" name=\"{0}.index\" autocomplete=\"off\" value=\"{1}\" />", collectionName, html.Encode(itemIndex)));
return BeginHtmlFieldPrefixScope(html, string.Format("{0}[{1}]", collectionName, itemIndex));
}
public static IDisposable BeginHtmlFieldPrefixScope(this HtmlHelper html, string htmlFieldPrefix)
{
return new HtmlFieldPrefixScope(html.ViewData.TemplateInfo, htmlFieldPrefix);
}
private static Queue<string> GetIdsToReuse(HttpContextBase httpContext, string collectionName)
{
string key = idsToReuseKey + collectionName;
var queue = (Queue<string>)httpContext.Items[key];
if (queue == null)
{
httpContext.Items[key] = queue = new Queue<string>();
var previouslyUsedIds = httpContext.Request[collectionName + ".index"];
if (!string.IsNullOrEmpty(previouslyUsedIds))
foreach (string previouslyUsedId in previouslyUsedIds.Split(','))
queue.Enqueue(previouslyUsedId);
}
return queue;
}
private class HtmlFieldPrefixScope : IDisposable
{
private readonly TemplateInfo templateInfo;
private readonly string previousHtmlFieldPrefix;
public HtmlFieldPrefixScope(TemplateInfo templateInfo, string htmlFieldPrefix)
{
this.templateInfo = templateInfo;
previousHtmlFieldPrefix = templateInfo.HtmlFieldPrefix;
templateInfo.HtmlFieldPrefix = htmlFieldPrefix;
}
public void Dispose()
{
templateInfo.HtmlFieldPrefix = previousHtmlFieldPrefix;
}
}
}
}