@model Wen.BooksStore.WebUI.Models.BookDetailsViewModels @{ ViewBag.Title = "Books"; } @foreach (var item in Model.Books) { <div> <h3>@item.Name</h3> @item.Description <h4>@item.Price.ToString("C")</h4> <br /> <hr /> </div> } <div> @Html.PageLinks(Model, x => Url.Action("Details", new { pageIndex = x, category = Model.CurrentCategory })) </div>
4.路由区域也应当修改一下
RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}", defaults: new { controller = "Book", action = "Details" } ); routes.MapRoute( name: null, url: "{controller}/{action}/{category}", defaults: new { controller = "Book", action = "Details" } ); routes.MapRoute( name: null, url: "{controller}/{action}/{category}/{pageIndex}", defaults: new { controller = "Book", action = "Details", pageIndex = UrlParameter.Optional } ); }
5.现在新建一个名为 NavController 的控制器,并添加一个名为Sidebar 的方法,专门用于渲染左侧边栏。
不过返回的 View 视图类型变成 PartialView 分部视图类型:
public PartialViewResult Sidebar(string category = null) { var categories = _bookRepository.Books.Select(x => x.Category).Distinct().OrderBy(x => x); return PartialView(categories); }
在方法体在右键,添加一个视图,勾上创建分部视图。
Sidebar.cshtml 修改为:
@model IEnumerable<string> <ul> <li>@Html.ActionLink("所有分类", "Details", "Book")</li> @foreach (var item in Model) { <li>@Html.RouteLink(item, new { controller = "Book", action = "Details", category = item, pageIndex = 1 }, new { @class = item == ViewBag.CurrentCategory ? "selected" : null })</li> } </ul>
MVC 框架具有一种叫作“子动作(Child Action)”的概念,可以适用于重用导航控件之类的东西,使用类似 RenderAction() 的方法,在当前的视图中输出指定的动作方法。
因为需要在父视图中呈现另一个 Action 中的分部视图,所以原来的_Layout.cshtml布局页修改如下:
现在,启动的结果应该和图 1 是一样的,尝试点击左侧边栏的分类,观察主区域的变化情况。
二、加入购物车
图 2
界面的大体功能如图 2,在每本图书的区域新增一个链接(添加到购物车),会跳转到一个新的页面,显示购物车的详细信息 - 购物清单,也可以通过“结算”链接跳转到一个新的页面。
购物车是应用程序业务域的一部分,因此,购物车实体应该为域模型。
1.添加两个类:
Cart.cs 有添加、移除、清空和统计功能:
/// <summary> /// 购物车 /// </summary> public class Cart { private readonly List<CartItem> _cartItems = new List<CartItem>(); /// <summary> /// 获取购物车的所有项目 /// </summary> public IList<CartItem> GetCartItems => _cartItems; /// <summary> /// 添加书模型 /// </summary> /// <param></param> /// <param></param> public void AddBook(Book book, int quantity) { if (_cartItems.Count == 0) { _cartItems.Add(new CartItem() { Book = book, Quantity = quantity }); return; } var model = _cartItems.FirstOrDefault(x => x.Book.Id == book.Id); if (model == null) { _cartItems.Add(new CartItem() { Book = book, Quantity = quantity }); return; } model.Quantity += quantity; } /// <summary> /// 移除书模型 /// </summary> /// <param></param> public void RemoveBook(Book book) { var model = _cartItems.FirstOrDefault(x => x.Book.Id == book.Id); if (model == null) { return; } _cartItems.RemoveAll(x => x.Book.Id == book.Id); } /// <summary> /// 清空购物车 /// </summary> public void Clear() { _cartItems.Clear(); } /// <summary> /// 统计总额 /// </summary> /// <returns></returns> public decimal ComputeTotalValue() { return _cartItems.Sum(x => x.Book.Price * x.Quantity); } }
CartItem.cs 表示购物车中的每一项: