MVC项目实践,在三层架构下实现SportsStore-05,实现导航
SportsStore是《精通ASP.NET MVC3框架(第三版)》中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器、URL优化、导航、分页、购物车、订单、产品管理、图像上传......是不错的MVC实践项目,但该项目不是放在多层框架下开发的,离真实项目还有一段距离。本系列将尝试在多层框架下实现SportsStore项目,并用自己的方式实现一些功能。
本篇为系列第五篇,包括:
■ 8、导航
8、导航
创建NavController,派生于BaseController:
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using MySportsStore.IBLL;
using Ninject; namespace MySportsStore.WebUI.Controllers
{
public class NavController : BaseController
{
[Inject]
public IProductService ProductService { get; set; } public NavController()
{
this.AddDisposableObject(ProductService);
} public PartialViewResult Menu(string category = null)
{
ViewBag.SelectedCategory = category;
IEnumerable<string> categories =
ProductService.LoadEntities(p => true).Select(p => p.Category).Distinct().OrderBy(p => p);
return PartialView(categories);
}
}
}
为什么有category参数?
为了让当前点击、选中的分类高亮显示。这里的category轨迹是:
→前端视图点击分类名称,并把分类名称赋值给路由变量category
→Nav控制器的Menu()方法接收到category,把其放到ViewBag中,再次传回前端视图
→前端视图在遍历所有分类名称的时候,如果当下分类名称与ViewBag中的相同,就为当下分类添加一个CSS,即高亮显示
需要为category赋上一个默认值,因为在点击分类名称之前,category为null。
在Nav/Menu.cshtml部分视图中,需要把category和page传递到Product控制器中的Nav()方法中:
@model IEnumerable<string>
@Html.ActionLink("Home","List","Product")
@foreach (var link in Model)
{
@Html.RouteLink(link, new {controller = "Product", action = "List", category = link, page = 1},
new {@class = link == ViewBag.SelectedCategory? "selected" : null})
}
在Views/Shared下的_Layout.cstml中显示加载分类部分视图:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="header">
<div class="title">体育用品商店</div>
</div>
<div id="categories">
@{Html.RenderAction("Menu","Nav");}
</div>
<div id="content">
@RenderBody()
</div> @Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</body>
</html>
根据点击分类传递的路由参数,在Product控制器的Nav方法中,还需要考虑到category,再对集合进行筛选。并且,还要考虑当没有点击导航分类名称的时候,category为null:
using System.Web.Mvc;
using MySportsStore.IBLL;
using MySportsStore.WebUI.Models;
using Ninject; namespace MySportsStore.WebUI.Controllers
{
public class ProductController : BaseController
{
[Inject]
public IProductService ProductService { get; set; } public ProductController()
{
this.AddDisposableObject(ProductService);
} public int PageSize = 4;
public ViewResult List(string category, int page = 1)
{
int totalCount = 0;
ProductsListViewModel viewModel = new ProductsListViewModel()
{
Products = ProductService.LoadPageEntities(p => category == null ? true : p.Category == category, p => p.Id, PageSize, page, out totalCount, true),
PagingInfo = new PagingInfo(){CurrentPage = page, ItemsPerPage = PageSize, TotalItems = category == null ? ProductService.Count(p => true) : ProductService.Count(p => p.Category == category)},
CurrentCategory = category
};
return View(viewModel);
} }
}
以上,在视图模型ProductsListViewModel中添加了CurrentCategory属性,这个属性值是要交给分页的:
using System.Collections.Generic;
using MySportsStore.Model; namespace MySportsStore.WebUI.Models
{
public class ProductsListViewModel
{
public IEnumerable<Product> Products { get; set; }
public PagingInfo PagingInfo { get; set; }
public string CurrentCategory { get; set; }
}
}
在Product/List.cshtml视图的分页部分,需要把CurrentCategory值赋值给路由变量category:
@model MySportsStore.WebUI.Models.ProductsListViewModel
@{
ViewBag.Title = "List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@foreach (var item in Model.Products)
{
Html.RenderPartial("PrductSummary", item);
}
<div class="pager">
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x, category = Model.CurrentCategory}))
</div>
运行:

为了让URL更好看,需要考虑如下情境下的URL:
● 运行默认页的时候
● 点击分页的时候
● 点击导航分类的时候
● 点击导航分类后,再点击分页的时候
调整URL为:
routes.MapRoute(
null,
"", //匹配空的URL,如"/"
new{controller = "Product", action = "List", category = (string)null, page = 1}
); routes.MapRoute(
null,
"Page{page}", //匹配"/Page1",当点击分页的时候
new {controller = "Product", action = "List", category = (string)null},
new {page = @"\d+"} //约束page为数字
); routes.MapRoute(
null,
"{category}", //匹配 "/Soccer",当点击导航分类的时候
new {controller = "Product", action = "List", page = 1}
); routes.MapRoute(
null,
"{category}/Page{page}", //匹配"/Soccer/Page1",当点击导航分类,在点击分页的时候
new {controller = "Product", action = "List"},
new {page = @"\d+"}
);
运行:
源码在这里。
“MVC项目实践,在三层架构下实现SportsStore”系列包括:
MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构
MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等
MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层
MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等
MVC项目实践,在三层架构下实现SportsStore-04,实现分页
MVC项目实践,在三层架构下实现SportsStore-05,实现导航
MVC项目实践,在三层架构下实现SportsStore-06,实现购物车
MVC项目实践,在三层架构下实现SportsStore-07,实现订单提交
MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器
MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务
MVC项目实践,在三层架构下实现SportsStore-10,连接字符串的加密和解密
MVC项目实践,在三层架构下实现SportsStore-11,使用Knockout实现增删改查
MVC项目实践,在三层架构下实现SportsStore-05,实现导航的更多相关文章
- MVC项目实践,在三层架构下实现SportsStore,从类图看三层架构
在"MVC项目实践,在三层架构下实现SportsStore-02,DbSession层.BLL层"一文的评论中,博友浪花一朵朵建议用类图来理解本项目的三层架构.于是就有了本篇: I ...
- MVC项目实践,在三层架构下实现SportsStore-02,DbSession层、BLL层
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- MVC项目实践,在三层架构下实现SportsStore-01,EF Code First建模、DAL层等
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- MVC项目实践,在三层架构下实现SportsStore-03,Ninject控制器工厂等
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- MVC项目实践,在三层架构下实现SportsStore-04,实现分页
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- MVC项目实践,在三层架构下实现SportsStore-06,实现购物车
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- MVC项目实践,在三层架构下实现SportsStore-07,实现订单提交
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- MVC项目实践,在三层架构下实现SportsStore-08,部署到IIS服务器
SportsStore是<精通ASP.NET MVC3框架(第三版)>中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器.URL优化.导航.分页.购物车.订单.产品管 ...
- MVC项目实践,在三层架构下实现SportsStore-09,ASP.NET MVC调用ASP.NET Web API的查询服务
ASP.NET Web API和WCF都体现了REST软件架构风格.在REST中,把一切数据视为资源,所以也是一种面向资源的架构风格.所有的资源都可以通过URI来唯一标识,通过对资源的HTTP操作(G ...
随机推荐
- php任何优化的方式下这样第个列表都是再次查询
我们的代码经理是这样的:计算总行数:select count(*) from tablename where -..查询列表select * from tablename where - limit- ...
- [转]如何:定义和处理 SOAP 标头
本文转自:http://msdn.microsoft.com/zh-cn/library/vstudio/8728chd5(v=vs.100).aspx 本主题专门介绍一项旧有技术.现在应通过使用以下 ...
- Functional programming
In computer science, functional programming is a programming paradigm, a style of building the struc ...
- Apache Storm 衍生项目之2 -- Trident-ML
欢迎转载,转载请注明出处,徽沪一郎,谢谢. 楔子 或许谈起storm是大数据实时计算框架已经让你不明觉厉,如果说storm还可以跟机器学习算法(ml)有机的结合在一起,是不是更加觉着高大尚呢.trid ...
- 拦截webview调用系统浏览器打开链接
给WebView设置自定义的WebViewClient即可 webview.setWebViewClient(new WebViewClient(){ @Override public boolean ...
- ThinkPHP验证码刷新随机数
貌似因为IE的内核不支持重复,,所以要加个随机数..在代码中,,发现火狐的也不行..加了随机数后就可以了 <label class="img"><img id=& ...
- PL/SQL Developer 显示中文乱码问题
简单版本: 首先,通过 select userenv('language') from dual; 查询oracle服务器端的编码,如为:AMERICAN_AMERICA.ZHS16GBK; 在我们的 ...
- Python浮点数控制小数精度
将精度高的浮点数转换成精度低的浮点数. 1.round()内置方法 这个是使用最多的,刚看了round()的使用解释,也不是很容易懂.round()不是简单的四舍五入的处理方式. For the bu ...
- 解决mysql数据库连接问题
设置mysql远程连接root权限 在远程连接mysql的时候应该都碰到过,root用户无法远程连接mysql,只可以本地连,对外拒绝连接.需要建立一个允许远程登录的数据库帐户,这样才可以进行在远程操 ...
- egrep 查找IP
1. egrep '([^0-9]|\<)(([0-1]?[0-9]{0,2}|([2]([0-4][0-9]|[5][0-5])))\.){3}([0-1]?[0-9]{0,2}|([2]([ ...