У меня есть частичное представление, которое привязано к объекту Корзина. Корзина имеет коллекцию 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, но я не мог понять, как передать Продукт из модели в мои действия вместо идентификатора.
Основная проблема, однако, заключается в том, что я довольно глупо завернул всю корзину в форму, чтобы можно было отправить обратно значения, а затем провел целый час, размышляя, почему в IE все работает неправильно - doh! вложенные формы
Так что я застрял на том, как обойти это. Я хочу иметь возможность удалять элементы по отдельности, но разрешить пользователю изменять количество элементов, а затем сразу передавать все изменения контроллеру. Я не могу использовать ссылки для своего действия по удалению, так как мне нужно было бы использовать javascript для принудительной публикации, и все должно работать без включенного javascript.
[Update]
Было бы лучшим решением разрешить обновления моего пользовательского связывателя модели? Таким образом, я мог бы внести изменения в свое представление и отправить объект корзины обратно в контроллер - хотя я не уверен, возможно ли это с дочерними коллекциями (Cart.CartItems).
Я просматривал такие сайты, как Amazon, и казалось, что они оборачивают всю корзину в форму, и как глобальные кнопки обновления, так и отдельные кнопки удаления элементов возвращаются к тому же действию, когда JavaScript отключен.
Любая помощь будет оценена.
Спасибо,
Бен