Главная страница   /   9.2. Завершаем функционал для корзины (ASP.NET MVC 4

ASP.NET MVC 4

ASP.NET MVC 4

Адам Фриман

9.2. Завершаем функционал для корзины

Теперь, когда пользовательский механизм связывания данных создан, мы можем завершить функциональность корзины, добавив две новые функции. Первая позволит пользователю удалять товар из корзины. Вторая будет отображать виджет корзины в верхней части страницы.

Удаление товаров из корзины

Мы уже определили и проверили метод действия RemoveFromCart в контроллере. Чтобы позволить пользователю удалять товары, нужно только сделать этот метод доступным в представлении, для чего мы добавим кнопку Remove в каждую строку представления для корзины. Изменения в Views/Cart/Index.cshtml показаны в листинге 9-4.

Листинг 9-4: Создаем кнопку Remove
<tbody>
	@foreach (var line in Model.Cart.Lines) {
		<tr>
			<td align="center">@line.Quantity</td>
			<td align="left">@line.Product.Name</td>
			<td align="right">@line.Product.Price.ToString("c")</td>
			<td align="right">@((line.Quantity * line.Product.Price).ToString("c"))</td>
			<td>
				@using (Html.BeginForm("RemoveFromCart", "Cart")) {
					@Html.Hidden("ProductId", line.Product.ProductID)
					@Html.HiddenFor(x => x.ReturnUrl)
					<input class="actionButtons" type="submit" value="Remove" />
				}
			</td>
		</tr>
	}
</tbody>

Примечание

Мы можем использовать строго типизированный вспомогательный метод Html.HiddenFor, чтобы создать скрытое поле для свойства модели ReturnUrl, но мы должны использовать строко-ориентированный вспомогательный метод Html.Hidden, чтобы сделать то же самое для поля Product ID. Если мы запишем Html.HiddenFor(x => line.Product.ProductID), вспомогательный метод визуализирует скрытое поле под названием line.Product.ProductID. Имя поля не будет совпадать с именами параметров метода действия CartController.RemoveFromCart, из-за чего механизмы связывания по умолчанию не будут работать и MVC Framework не сможет вызвать метод.

Вы можете проверить работу кнопок Remove, если запустите приложение, добавите какие-нибудь товары в корзину и кликните по одной из них. Результат показан на рисунке 9-1.

Рисунок 9-1: Удаление товара из корзины

Добавляем виджет корзины

У нас уже готова функционирующая корзина, но еще есть проблема с тем, как она интегрирована в интерфейс. Пользователи могут просмотреть ее содержимое, только открыв страницу корзины. А открыть страницу корзины они смогут, только добавив в нее новый товар.

Чтобы решить эту проблему, мы добавим виджет, который выводит краткую информацию о корзине и при нажатии отобразит ее содержимое. Мы сделаем это почти также, как добавляли виджет навигации - используя действие, вывод которого будет внедрен в макет Razor.

Для начала нам нужно добавить в класс CartController простой метод, показанный в листинге 9-5.

Листинг 9-5: Добавляем метод Summary в контроллер Cart
public PartialViewResult Summary(Cart cart) {
	return PartialView(cart);
}

Как видите, это очень простой метод. Он просто визуализирует представление, предоставляя текущий объект Cart (который будет получен с помощью нашего пользовательского механизма связывания), в качестве данных представления. Нам нужно создать частичное представление, которое будет отображаться в ответ на вызов метода Summary. Кликните правой кнопкой мыши метод Summary и выберите Add View из контекстного меню. Назовите представление Summary, отметьте опцию Create as strongly typed view и установите класс модели Cart, как показано на рисунке 9-2. Мы хотим внедрить частичное представление в страницу, так что отметьте опцию Create as a partial view.

Рисунок 9-2: Добавляем представление Summary

Измените новое частичное представление так, чтобы оно соответствовало листингу 9-6.

Листинг 9-6: Частичное представление Summary
@model SportsStore.Domain.Entities.Cart

<div id="cart">
	<span class="caption">
		<b>Your cart:</b>
		@Model.Lines.Sum(x => x.Quantity) item(s),
		@Model.ComputeTotalValue().ToString("c")
	</span>

	@Html.ActionLink("Checkout", "Index", "Cart", new { returnUrl = Request.Url.PathAndQuery }, null)
</div>

Это простое представление, которое отображает количество товаров в корзине, их общую стоимость и ссылку, по которой можно просмотреть содержимое корзины. Теперь, когда мы определили представление, которое возвращает метод действия Summary, мы можем включить результат рендеринга в файл _Layout.cshtml, как показано в листинге 9-7.

Листинг 9-7: Добавляем частичное представление Summary в макет
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width" />
	<title>@ViewBag.Title</title>
	<link href="~/Content/Site.css" type="text/css" rel="stylesheet" />
</head>
<body>
	<div id="header">
		@{Html.RenderAction("Summary", "Cart");}
		<div class="title">SPORTS STORE</div>
	</div>
	<div id="categories">
		@{ Html.RenderAction("Menu", "Nav"); }
	</div>
	<div id="content">
		@RenderBody()
	</div>
</body>
</html>

Напоследок мы добавим некоторые дополнительные правила CSS для форматирования элементов в частичное представление. Добавьте стили из листинга 9-8 в файл Site.css проекта SportsStore.WebUI.

Листинг 9-8: Добавляем стили в Site.css
DIV#cart { float:right; margin: .8em; color: Silver;
	background-color: #555; padding: .5em .5em .5em 1em; }
DIV#cart A { text-decoration: none; padding: .4em 1em .4em 1em; line-height:2.1em;
	margin-left: .5em; background-color: #333; color:White; border: 1px solid black;}

Запустив приложение, вы можете увидеть виджет корзины. Количество элементов и их общая стоимость увеличивается, когда вы добавляете товар в корзину, как показано на рисунке 9-3.

Рисунок 9-3: Виджет корзины

Благодаря этому дополнению пользователи будут знать, что у них в корзине, и использовать очевидный способ для перехода к оплате. Вы еще раз можете убедиться, как легко использовать RenderAction для внедрения вывода метода действия в страницу. Эта техника также позволяет разделить функциональность приложения на отдельные многократно используемые блоки.