我有一个局部视图绑定到对象Cart。购物车有一系列CartLines。我的观点如下:
<tbody>
<% foreach (var line in Model.Lines) { %>
<tr>
<td align="center"><%=Html.CatalogImage(line.Product.DefaultImage, 80) %></td>
<td align="left">
<%=Html.ActionLink(line.Product.Name, "Product", "Catalog",
new { productId = line.Product.Id }, new { title = "View " + line.Product.Name })%>
</td>
<td align="right"><%= line.Product.Price.ToString("c")%></td>
<td align="center">
<%=Html.Hidden("lines[" + i + "].key", line.Product.Id) %>
<%=Html.TextBox("lines[" + i + "].value", line.Quantity, new { @class = "quantity" })%>
</td>
<td align="right"><%= (line.LineTotal).ToString("c")%></td>
<td>
<%using (Ajax.BeginForm("RemoveFromCart", "Cart",
new {ProductId = line.Product.Id, returnUrl = ViewData["returnUrl"]},
new AjaxOptions { UpdateTargetId="cart", LoadingElementId="loading" }))
{%>
<input type="image" src="<%=AppHelper.ImageUrl("delete.gif")%>" value="Remove item" />
<%} %>
</td>
</tr>
<% i++; } %>
</tbody>
有两点需要注意。首先是我每行使用一个表单来删除项目。
第二个是我试图允许用户更改订单项的数量,然后点击更新按钮将所有更改传递给控制器操作:
// POST: /Cart/Update
[HttpPost]
public ActionResult Update(Cart cart, IDictionary<int,int> lines, string returnUrl)
{
foreach (var line in lines) {
Product p = _catalogService.GetProduct(line.Key);
cart.UpdateItem(p, line.Value);
}
if (Request.IsAjaxRequest())
return PartialView("Cart", cart);
else
return RedirectToAction("Index", new { returnUrl });
}
请注意我使用的是字典,因为我只关心产品和数量。我不太喜欢在调用cart.UpdateItem之前需要再次检索产品的事实,但我无法弄清楚如何将产品从模型传递到我的操作而不是id。
然而,主要的问题是相当愚蠢的是我把整个购物车包裹在一个表格中,以便我可以回发价值,然后花了一个小时的时间想知道为什么IE中没有正常工作 - doh!嵌套表格所以我被困在如何绕过这个。我希望能够单独删除项目,但允许用户更改项目数量,然后立即将所有更改传递给控制器。我不能使用链接进行删除操作,因为我需要使用javascript来强制发布帖子,所有内容都必须在没有启用javascript的情况下运行。
[更新]
更好的解决方案是允许更新自定义模型绑定器吗?这样我就可以在视图中进行更改并将购物车对象发回控制器 - 尽管我不确定这是否可以用于子集合(Cart.CartItems)。 我已经看过像亚马逊这样的网站,看起来它们将整个购物车包裹在一个表单中,并且当禁用javascript时,全局更新按钮和indidivual删除项按钮都会回复到相同的操作。 任何帮助将不胜感激。
谢谢, 本
答案 0 :(得分:0)
这里只有一种方式,这就是丑陋的方式。一切都有1个表格。 然后在操作中你必须检查按下了哪个按钮(你得到了请求中按钮的名称)。
随着firefox和ie的差异变得更加丑陋。如果您按下按钮ie或firefox(不记得哪一个)不仅发送按下按钮的名称,还发送按钮按下的位置。
如果您的解决方案可以依赖于支持JS的浏览器,那么您有更多选择。但那是另一个故事。