MVC3。 Ajax确认来了两次

时间:2012-03-19 22:09:02

标签: asp.net-mvc-3

我有一份产品清单。每行都有“删除”操作。当我尝试删除任何行时,一切都是真的,但在第二次删除之后,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>

2 个答案:

答案 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)删除后重新绑定整个项目集以删除项目已被删除。

只要您继续拥有客户认为尚未删除的项目,您就会在每次点击时继续“删除这两项”。