MVC项目实践,在三层架构下实现SportsStore-04,实现分页
SportsStore是《精通ASP.NET MVC3框架(第三版)》中演示的MVC项目,在该项目中涵盖了MVC的众多方面,包括:使用DI容器、URL优化、导航、分页、购物车、订单、产品管理、图像上传......是不错的MVC实践项目,但该项目不是放在多层框架下开发的,离真实项目还有一段距离。本系列将尝试在多层框架下实现SportsStore项目,并用自己的方式实现一些功能。
本篇为系列第四篇,包括:
■ 7、添加分页
7、添加分页
关于分页,是一系列的a标签,可以通过扩展HtmlHelper来实现。产生分页a标签的大致思路为:
1、扩展方法需要遍历循环所有页数,而所有页数是由"总记录数/页容量",再经过计算得到。
2、可以把总记录数、页容量、所有页数等封装成一个类提供给扩展方法。
3、而包含总记录数、页容量、所有页数等这个类实例,当然是由控制器方法提供。
创建PagingInfo来包装分页相关信息:
using System; namespace MySportsStore.WebUI.Models
{
public class PagingInfo
{
public int TotalItems { get; set; }
public int ItemsPerPage { get; set; }
public int CurrentPage { get; set; } public int TotalPages
{
get { return (int)Math.Ceiling((decimal) TotalItems/ItemsPerPage); }
}
}
}
关于CurrentPage属性,扩展方法会根据它来确定是否要给a标签添加一个表示选中、当前页的css属性。
扩展方法遍历循环所有页数,产生数字a标签,并根据PagingInfo的CurrentPage属性来判断是否要给a标签加上一个用来表示选中、当前页的属性:
using System;
using System.Text;
using System.Web.Mvc;
using MySportsStore.WebUI.Models; namespace MySportsStore.WebUI.HtmlHelpers
{
public static class PagingHelpers
{
public static MvcHtmlString PageLinks(this HtmlHelper html,
PagingInfo pagingInfo,
Func<int, string> pageUrl)
{
StringBuilder result = new StringBuilder();
for (int i = 1; i <= pagingInfo.TotalPages; i++)
{
TagBuilder tag = new TagBuilder("a");
tag.MergeAttribute("href", pageUrl(i));
tag.InnerHtml = i.ToString();
if (i == pagingInfo.CurrentPage)
{
tag.AddCssClass("selected");
}
result.Append(tag.ToString());
}
return MvcHtmlString.Create(result.ToString());
}
}
}
以上的pageUrl是一个委托,输入页面,输出一个包含查询字符串的URL。
而添加的扩展方法需要在Views文件夹下的Web.config中注册后,才能在视图页中使用:
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
......
<add namespace="MySportsStore.WebUI.HtmlHelpers" />
</namespaces>
</pages>
</system.web.webPages.razor>
当然,分页是有关Product的分页,在显示Product列表的视图页上,除了分页,还有一个Product的集合,于是,我们可以把分页和Product的集合整合成一个视图模型:
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; }
}
}
Product控制器的List方法职责很明确:就是根据前台视图传递过来表示当前页的page变量,产生一个ProductsListViewModel的实例,传递给前台视图:
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(int page = 1)
{
int totalCount = 0;
ProductsListViewModel viewModel = new ProductsListViewModel()
{
Products = ProductService.LoadPageEntities(p => true, p => p.Id, PageSize, page, out totalCount, true),
PagingInfo = new PagingInfo(){CurrentPage = page, ItemsPerPage = PageSize, TotalItems = ProductService.Count(p => true)}
};
return View(viewModel);
} }
}
Product/List.cshtml强类型视图:
@model MySportsStore.WebUI.Models.ProductsListViewModel
@{
ViewBag.Title = "List";
Layout = "~/Views/Shared/_Layout.cshtml";
}
@foreach (var item in Model.Products)
{
<div class="item">
<h3>@item.Name</h3>
@item.Description
<h4>@item.Price.ToString("c")</h4>
</div>
}
<div class="pager">
@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new {page = x}))
</div>
运行,得到如下结果:

让人欣慰的是:对Prouct列表进行了分页处理。稍有不足的是:页面链接以http://localhost/?page2这种形式存在。我们在路由设置中设置如下路由:
routes.MapRoute(
null,
"Page{page}",
new {controller = "Product", action = "List"}
); routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
);
运行,得到如下结果:

在Views/Shared/_Layout.chstml中布局页面,设置CSS,呈现如下页面:

在Product/List.cshtml视图页中,还可以把显示产品的逻辑放到一个部分视图中,以便重复利用。在Views/Shared下创建ProductSummary.cshtml强类型部分视图:
@model MySportsStore.Model.Product <div class="item">
<h3>@Model.Name</h3>
@Model.Description
<h4>@Model.Price.ToString("c")</h4>
</div>
最后,在Product/List.cshtml视图页中,在遍历Product集合的时候,加载部分视图:
@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}))
</div>
至此,完成分页。
源码在这里。
“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-04,实现分页的更多相关文章
- 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-05,实现导航
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 ...
随机推荐
- C# - 杨涛分页控件AspNetPager
http://www.webdiyer.com/downloads/ 前台 <%@ Page Language="C#" AutoEventWireup="true ...
- 基本Java数据类型
一.整型:java中的基本数据类型byte,占用1个字节,8位 取值范围:0000 0000 ~ 1111 1111 (-128 ~ 127) 为什么不是:0000 0000 ~ 1111 1 ...
- 【iHMI43 4.3寸液晶模块】demo例程(版本1.03)发布
============================== 技术论坛:http://www.eeschool.org 博客地址:http://xiaomagee.cnblogs.com 官方网店:h ...
- 解决电脑访问Discuz!手机版(支持触屏版)
discuz电脑访问手机版的方法现在需要来修改一下2个文件,即可用电脑浏览discuz的手机版本:找到./source/function/function_core.php 文件,查找 : funct ...
- 图片lightbox2
1. 官网下载 http://lokeshdhakar.com/projects/lightbox2/ 2.引入 css jquery js 3. HTML格式 <a href=" ...
- hardware control language
Computer Systems A Programmer's Perspective Second Edition We then provide some background on digita ...
- Java中常用的内存区域
在Java中主要存在4块内存空间,这些内存空间的名称及作用如下. 1. 栈内存空间: 保存所有对象名称(更准确的说是保存了引用的堆内存空间的地址). 2. 堆内存空间: 保存每个对象的具体属性内容 ...
- Git学习笔记(持续更新)
1.强制同步为远程的代码 远程仓库回退了commit的情况下(第2条描述之情况),强制同步远程的代码到本地 #更新远程最新的所有代码,但是不merge或者rebase git fetch --all ...
- OC接收数据时毫秒转date时间最简略方法
一般项目中接收后台的数据会收到毫秒格式的date,需要换算成正规日期格式,这时候我们的好朋友command + c 和 command + v就得出来帮忙了: 可以复制使用如下方法: + (NSStr ...
- TP自带的缓存机制
原文章出处: http://blog.163.com/liwei1987821@126/blog/static/172664928201422133218356/ 动态缓存 Cache缓存类 vie ...