我有一份产品清单。每行都有“删除”操作。当我尝试删除任何行时,一切都是真的,但在第二次删除之后,ajax确认会出现两次。请帮忙。
有产品清单视图。
@model IEnumerable<Domain.Entities.Product>
@{
ViewBag.Title = "Products";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<h1>Products</h1>
<table class="Grid">
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>@item.Name</td>
<td>@item.Description</td>
<td>@item.Price</td>
<td>
@using (Ajax.BeginForm("DeleteProduct", "Admin",
new AjaxOptions {
Confirm="Product was deleted!",
UpdateTargetId="DeleteProduct"
}))
{
@Html.Hidden("Id", item.Id)
<input type="image" src="../Images/Icons/DeleteIcon.jpg" />
}
</td>
</tr>
}
</table>
有AdminController
[Authorize]
public class AdminController : Controller
{
private IProductRepository productRepository;
public AdminController(IProductRepository productRepository)
{
this.productRepository= productRepository;
}
public ViewResult Products()
{
return View(productRepository.Products);
}
[HttpPost]
public ActionResult DeleteProduct(int id)
{
Product prod = productRepository.Products.FirstOrDefault(p => p.Id == id);
if (prod != null)
{
productRepository.DeleteProduct(prod);
TempData["message"] = string.Format("{0} was deleted", prod.Name);
}
return RedirectToAction("Products");
}
}
最后_AdminLayout.cshtml
<html>
<head>
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Admin.css")" rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
</head>
<body>
<div id="DeleteProduct">
@if (TempData["message"] != null) {
<div class="Message">@TempData["message"]</div>
}
@RenderBody()
</div>
</body>
</html>
答案 0 :(得分:3)
此处的问题是您使用AJAX调用DeleteProduct
操作,此操作正在执行“重定向到产品”操作。除了Products操作返回完整的HTML而不是部分HTML。因此,您将jquery.unobtrusive-ajax.js
两次注入DOM。因此,您在第二次删除时获得2次确认,在第三次删除时获得3次,依此类推。
首先定义一个包含表记录(~/Views/Admin/_Products.cshtml
)的部分:
@model IEnumerable<Domain.Entities.Product>
<div>@ViewData["message"]</div>
<table class="Grid">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>@item.Name</td>
<td>@item.Description</td>
<td>@item.Price</td>
<td>
@using (Ajax.BeginForm("DeleteProduct", "Admin",
new AjaxOptions {
Confirm = "Are you sure you wanna delete this product?",
UpdateTargetId = "products"
})
)
{
@Html.Hidden("Id", item.Id)
<input type="image" src="@Url.Content("~/Images/Icons/DeleteIcon.jpg")" alt="Delete" />
}
</td>
</tr>
}
</tbody>
</table>
然后修改您的主视图,以便它使用此部分:
@model IEnumerable<Product>
@{
ViewBag.Title = "Products";
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
<h1>Products</h1>
<div id="products">
@Html.Partial("_Products")
</div>
最后修改你的DeleteProduct
控制器操作,使其不再进行任何重定向,但在删除记录后返回partial:
[HttpPost]
public ActionResult DeleteProduct(int id)
{
Product prod = productRepository.Products.FirstOrDefault(p => p.Id == id);
if (prod != null)
{
productRepository.DeleteProduct(prod);
ViewData["message"] = string.Format("{0} was deleted", prod.Name);
}
return PartialView("_Products", productRepository.Products);
}
答案 1 :(得分:1)
您可以通过单个AJAX操作获得所有内容,因此单击“删除”会在第二次单击时找到要删除的两个项目。处理这个问题的方法是重置绑定项目时的一些魔力,所以a)删除的项目设置为显示已经确认已经删除或b)删除后重新绑定整个项目集以删除项目已被删除。
只要您继续拥有客户认为尚未删除的项目,您就会在每次点击时继续“删除这两项”。