我正在编写一个电影应用程序,允许您租借电影(类似于Redbox)。我有一个包含表格的CheckOut购物车视图。每个表格行都有一个删除按钮,该按钮使用AJAX删除视图中的元素,并更新应用程序使用的SQL数据库。从购物车中删除任何物品后,用户应该能够单击“购买”并处理购物车中剩余的物品,而无需刷新页面。
我有一个包含OrderDetails列表的Order模型。每个OrderDetails项目都有有关电影的信息。该表将使用OrderDetails列表中的数据填充。
当我从购物车中删除物品并尝试使用表格中的值过帐表单时,就会出现问题。我的CheckOut HttpPost控制器方法接收了该模型,但是OrderDetail列表仍具有它在我从购物车中删除商品之前的原始商品计数。从逻辑上讲,没有数据绑定到属性,因为我删除了每条记录中的隐藏标签。
因为该列表包含我不需要的元素,所以处理该列表会导致垃圾数据进入数据库。
我试图在CheckOut HttpPost方法开始处理列表之前,先删除其垃圾元素。这很好用,但是我不想在发布表单后删除CheckOut方法中的任何内容。我希望列表中不包含元素。
CheckOut POST方法:
[HttpPost]
public IActionResult CheckOut(Order order)
{
if (ModelState.IsValid == false)
{
return View("CheckOut", order);
}
foreach (var orderDetailObj in order.OrderDetailsList)
{
_checkOutService.StoreMoviesInOrder(GetConnectionString(), order.OrderId, orderDetailObj);
}
return RedirectToAction("PurchaseSummary", new { Id = order.OrderId });
}
CheckOut.cshtml视图:
@model MovieContract.Order
...
@for (int i = 0; i < Model.OrderDetailsList.Count; i++)
{
<tr>
<td>
<input type="button" name="btnRemove" class="removeButton" value="Remove" onclick="Remove(this, '@Model.CartId', @Model.OrderDetailsList[i].Movie.FilmId)" />
</td>
<td hidden>
<input asp-for="@Model.OrderDetailsList[i].Movie.AddedToCart" value="@Model.OrderDetailsList[i].Movie.AddedToCart" hidden />
</td>
<td hidden>
<input asp-for="@Model.OrderDetailsList[i].Movie.FilmId" value="@Model.OrderDetailsList[i].Movie.FilmId" hidden />
</td>
<td>
<input asp-for="@Model.OrderDetailsList[i].Movie.FilmName" value="@Model.OrderDetailsList[i].Movie.FilmName" hidden />
@Model.OrderDetailsList[i].Movie.FilmName
</td>
<td>
<input asp-for="@Model.OrderDetailsList[i].Movie.GenreName" value="@Model.OrderDetailsList[i].Movie.GenreName" hidden />
@Model.OrderDetailsList[i].Movie.GenreName
</td>
<td>
<input asp-for="@Model.OrderDetailsList[i].Movie.PricePerDay" value="@Model.OrderDetailsList[i].Movie.PricePerDay" class="pricePerDay" hidden />
@Html.DisplayFor(modelItem => @Model.OrderDetailsList[i].Movie.PricePerDay)
</td>
<td hidden>
<input asp-for="@Model.OrderDetailsList[i].Movie.AmountOnHand" value="@Model.OrderDetailsList[i].Movie.AmountOnHand" hidden />
</td>
</tr>
}
对于AJAX,我只是拥有一个调用后控制器方法的AJAX函数。该方法从数据库中删除适当的项目,并返回NoContent();。成功后,AJAX将从视图中删除所需的行。
我希望在到达CheckOut HttpPost方法时,如果我决定从购物车中删除任何元素,则参数对象的list属性将包含较少的元素。我不需要每次从购物车中删除物品时都需要刷新整个页面来重建模型。
答案 0 :(得分:0)
这是一个工作示例:
查看
@model AjaxDeleteItem.Models.Order
<div>
<form method="post" asp-action="CheckOut">
<table class="table" id="table">
<thead>
<tr>
<th></th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.OrderDetailsList.Count; i++)
{
<tr class="count">
<td>
<input type="button" name="btnRemove" class="removeButton" value="Remove" onclick="Remove(this, @Model.OrderDetailsList[i].Id)" />
</td>
<td >
<input class="FilmId" asp-for="@Model.OrderDetailsList[i].Movie.FilmId" value="@Model.OrderDetailsList[i].Movie.FilmId" />
</td>
<td >
<input class="FilmName" asp-for="@Model.OrderDetailsList[i].Movie.FilmName" value="@Model.OrderDetailsList[i].Movie.FilmName" />
</td >
<td>
<input class="GenreName" asp-for="@Model.OrderDetailsList[i].Movie.GenreName" value="@Model.OrderDetailsList[i].Movie.GenreName" />
</td>
<td>
<input class="PricePerDay" asp-for="@Model.OrderDetailsList[i].Movie.PricePerDay" value="@Model.OrderDetailsList[i].Movie.PricePerDay" />
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Submit"/>
</form>
</div>
@section Scripts
{
<script>
function Remove(obj,id) {
$.ajax({
type: "post",
url: "/orders/deleteorderitem?id="+id,
success: function () {
$(obj).closest('tr').remove();
var count = $(" tbody tr").length;
var i = 0;
$("tbody tr").each(function () {
var row = $(this);
if (i < count)
{
row.find("input[class=FilmId]").attr("name", "OrderDetailsList[" + i + "].Movie.FilmId");
row.find("input[class=FilmName]").attr("name", "OrderDetailsList[" + i + "].Movie.FilmName");
row.find("input[class=GenreName]").attr("name", "OrderDetailsList[" + i + "].Movie.GenreName");
row.find("input[class=PricePerDay]").attr("name", "OrderDetailsList[" + i + "].Movie.PricePerDay");
i++;
}
});
},
error: function () {
alert("Fail to delete");
}
});
}
</script>
}
2.Controller:
[HttpPost]
public async Task<IActionResult> DeleteOrderItem(int id)
{
var orderdetail = await _context.OrderDetails.FindAsync(id);
_context.OrderDetails.Remove(orderdetail);
await _context.SaveChangesAsync();
return NoContent();
}
[HttpPost]
public IActionResult CheckOut(Order order)
{
if (ModelState.IsValid == false)
{
return View("Details", order.CartId);
}
//the stuff you want
}