Ajax 局部视图加载MVC时,列表中的编辑未保存
我是MVC新手。我有一个视图,显示附加到Ajax 局部视图加载MVC时,列表中的编辑未保存,ajax,asp.net-mvc,Ajax,Asp.net Mvc,我是MVC新手。我有一个视图,显示附加到Quote(QuoteDetails)的产品。我还有一个用于“添加产品”的Ajax.ActionLink),它为要输入的另一个产品加载部分视图。问题在于,加载局部视图时,不会保存对不在局部视图中的其他产品所做的编辑。如果未加载局部视图,则对列出的产品所做的编辑可以很好地保存 以下是主视图的相关代码: @model CMSUsersAndRoles.Models.QuoteViewModel .... @Scripts.Render("~/Scripts/j
Quote
(QuoteDetails
)的产品。我还有一个用于“添加产品”的Ajax.ActionLink)
,它为要输入的另一个产品加载部分视图。问题在于,加载局部视图时,不会保存对不在局部视图中的其他产品所做的编辑。如果未加载局部视图,则对列出的产品所做的编辑可以很好地保存
以下是主视图的相关代码:
@model CMSUsersAndRoles.Models.QuoteViewModel
....
@Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="~/Scripts/jquery.mask.min.js"></script>
@using (Html.BeginForm())
{
....
@Html.HiddenFor(model => model.CustomerId)
@Html.LabelFor(model => model.QuoteId)
@Html.EditorFor(model => model.QuoteId, new { htmlAttributes = new { @readonly = "readonly", @class = "form-control" } })
@Html.ValidationMessageFor(model => model.QuoteId)
.... // more controls for properties of Quote
@Html.LabelFor(model => model.QuoteDetail)
<div id="QuoteDetails">
@for (int i = 0; i < Model.QuoteDetail.Count; i++)
{
@Html.HiddenFor(model => model.QuoteDetail[i].QuoteId, new { htmlAttributes = new { @class = "form-control" } })
....
@Html.EditorFor(model => model.QuoteDetail[i].SKU, new { htmlAttributes = new { @readonly = "readonly", @id = "SKU", @class = "form-control", style = "width: 100px" } })
@Html.EditorFor(model => model.QuoteDetail[i].Amount, new { htmlAttributes = new { @class = "form-control amount", style = "width: 95px" } })
@Html.ValidationMessageFor(model => model.QuoteDetail[i].Amount)
.... // more for controls for properties of QuoteDetail
@Ajax.ActionLink(" ", "DeleteProduct", "QuoteViewModel", new { quoteId = Model.QuoteDetail[i].QuoteId, quoteDetailId = (Model.QuoteDetail[i].QuoteDetailId) },
new AjaxOptions
{
HttpMethod = "POST",
Confirm = "Are you Sure You Want to Delete " + Model.QuoteDetail[i].ProductName,
}, new { @class = "btn btn-danger glyphicon glyphicon-trash" })
</div>
}
@Html.EditorFor(model => model.Subtotal, new { htmlAttributes = new { @class = "form-control subTotal", style = "width: 100px; float:right; clear:left; text-align:right" } })
@Ajax.ActionLink("Add product", "AddProduct", "QuoteViewModel", new { quoteId = Model.QuoteId, quoteDetailId = (Model.QuoteDetail.Count + 1) },
new AjaxOptions
{
UpdateTargetId = "QuoteDetails",
InsertionMode = InsertionMode.InsertAfter
})
}
@model CMSUsersAndRoles.Models.QuoteViewModel
....
@Scripts.Render(“~/Scripts/jquery.unobtrusiveajax.min.js”)
@使用(Html.BeginForm())
{
....
@Html.HiddenFor(model=>model.CustomerId)
@LabelFor(model=>model.QuoteId)
@EditorFor(model=>model.QuoteId,new{htmlAttributes=new{@readonly=“readonly”,@class=“form control”})
@Html.ValidationMessageFor(model=>model.QuoteId)
..//Quote属性的更多控件
@LabelFor(model=>model.QuoteDetail)
@对于(int i=0;imodel.QuoteDetail[i].QuoteId,new{htmlAttributes=new{@class=“form control”})
....
@Html.EditorFor(model=>model.QuoteDetail[i].SKU,new{htmlAttributes=new{@readonly=“readonly”、@id=“SKU”、@class=“form control”,style=“width:100px”})
@EditorFor(model=>model.QuoteDetail[i].Amount,new{htmlAttributes=new{@class=“表单控制量”,style=“width:95px”}})
@Html.ValidationMessageFor(model=>model.QuoteDetail[i].Amount)
..//more了解QuoteDetail属性的控件
@Ajax.ActionLink(“,”DeleteProduct“,”QuoteViewModel“,”新的{quoteId=Model.QuoteDetail[i].quoteId,quoteDetailId=(Model.QuoteDetail[i].quoteDetailId)},
新选择
{
HttpMethod=“POST”,
确认=“是否确实要删除”+Model.QuoteDetail[i].ProductName,
},新建{@class=“btn btn危险标志符号图标垃圾箱”})
}
@EditorFor(model=>model.Subtotal,new{htmlAttributes=new{@class=“form control Subtotal”,style=“width:100px;float:right;clear:left;text align:right”})
@ActionLink(“添加产品”、“添加产品”、“QuoteViewModel”,新的{quoteId=Model.quoteId,quoteDetailId=(Model.QuoteDetail.Count+1)},
新选择
{
UpdateTargetId=“QuoteDetails”,
InsertionMode=InsertionMode.InsertAfter
})
}
以下是局部视图:
@model CMSUsersAndRoles.Models.QuoteDetail
@{
ViewBag.Title = "EditQuoteDetail";
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
</head>
<body>
<div id="row" class="row">
<table>
@using (Html.BeginCollectionItem("quoteDetail"))
{
<tr>
@Html.HiddenFor(model => model.QuoteId, new { htmlAttributes = new { @class = "form-control" } })
@Html.EditorFor(model => model.SKU, new { htmlAttributes = new { @readonly = "readonly", @id = "SKU", @class = "form-control", style = "width: 100px" } })
@Html.DropDownListFor(model => model.ProductId, new SelectList(ViewBag.ProductData, "ProductId", "Name"), "---Select one---", new { style = "width: 300px !important", htmlAttributes = new { @id = "ProductName", @class = "ProductList" } });
.... // more controls for properties of QuoteDetail
@Ajax.ActionLink(" ", "DeleteProduct", "QuoteViewModel", new { quoteId = Model.QuoteId, quoteDetailId = (Model.QuoteDetailId) },
new AjaxOptions
{
HttpMethod = "POST",
Confirm = "Are you Sure You Want to Delete " + Model.ProductName,
}, new { @class = "btn btn-danger glyphicon glyphicon-trash" })
</tr>
}
</table>
</div>
@model CMSUsersAndRoles.Models.QuoteDetail
@{
ViewBag.Title=“EditQuoteDetail”;
布局=空;
}
@使用(Html.BeginCollectionItem(“quoteDetail”))
{
@HiddenFor(model=>model.QuoteId,new{htmlAttributes=new{@class=“form control”}})
@EditorFor(model=>model.SKU,new{htmlAttributes=new{@readonly=“readonly”,@id=“SKU”,@class=“form control”,style=“width:100px”})
@Html.DropDownListFor(model=>model.ProductId,新选择列表(ViewBag.ProductData,“ProductId”,“Name”),“---选择一个----”,新的{style=“width:300px!important”,htmlAttributes=new{@id=“ProductName”,@class=“ProductList”});
..//QuoteDetail属性的更多控件
@ActionLink(“,”DeleteProduct“,”QuoteViewModel“,”新的{quoteId=Model.quoteId,quoteDetailId=(Model.quoteDetailId)},
新选择
{
HttpMethod=“POST”,
确认=“是否确实要删除”+Model.ProductName,
},新建{@class=“btn btn危险标志符号图标垃圾箱”})
}
下面是控制器的操作:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(QuoteViewModel qvm,
[Bind(Include = "CustomerId,SalesRep,FirstName,LastName,Company,Address1,Address2,City,State,PostalCode,WorkPhone,CellPhone,Email,Discount,PaymentTerms")] Customer customer,
[Bind(Include = "QuoteId,QuoteDetailId,ProductId,ProductName,Amount,ListPrice,Discount,Price")] List<QuoteDetail> quoteDetails,
[Bind(Include = "QuoteId,CustomerId,Subtotal,Tax,Total,QuoteDate,GoodUntil,QuoteSent,DateApproved,DateOrdered")] Quote quote)
{
....
}
[HttpPost]
[ValidateAntiForgeryToken]
公共行动结果编辑(QuoteviewModelQVM,
[Bind(包括=“CustomerId、SalesRep、FirstName、LastName、Company、Address1、Address2、城市、州、邮政编码、工作电话、手机、电子邮件、折扣、付款条件”)]客户,
[Bind(Include=“QuoteId,QuoteDetail,ProductId,ProductName,Amount,ListPrice,折扣,Price”)]列出quoteDetails,
[Bind(包括=“QuoteId,CustomerId,小计,税,总计,QuoteDate,GoodUntil,QuoteSent,DateApproved,DateOrdered”)]Quote报价)
{
....
}
有人能帮忙吗?非常感谢您的帮助。您在这里使用了两种不同的技术来生成导致问题的收藏 在主视图中,您有一个
for
循环,用于为正在生成以零为基础的连续索引器的现有项生成控件,这是DefaultModelBinder
默认使用的。您的html将包括name
属性,例如
<input name="QuoteDetail[0].QuoteId"..../>
<input name="QuoteDetail[1].QuoteId"..../>
<input name="QuoteDetail[2].QuoteId"..../>
还包括一个
<input name="QuoteDetail.Index" value="xxxx" ... />
或者将循环更改为在每次迭代中使用包含BeginCollectionItem
方法的局部视图
@foreach(var item in Model.QuoteDetail)
{
@Html.Partial("xxxx", item) // replace xxxx with the name of your partial
}
我使用了解决方案2,效果很好。谢谢
@for (int i = 0; i < Model.QuoteDetail.Count; i++)
{
....
<input type="hidden" name="QuoteDetail.Index" value="@i" />
}
@foreach(var item in Model.QuoteDetail)
{
@Html.Partial("xxxx", item) // replace xxxx with the name of your partial
}