MVC 简单的分页思想与实现
ASP.NET MVC 简单的分页思想与实现
作为一个程序猿,数据分页是每个人都会遇到的问题。解决方案更是琳琅满目,花样百出。但基本的思想都是差不多的。
下面给大家分享一个简单的分页器,让初学者了解一下最简单的分页思想,以及在ASP.NET MVC中的简单实现与应用。
一,定义分页器类
在ASP.NET MVC中,分页的数据源可能是各种不同的类型,所以最好使用泛型来定义。
public class PagingHelper <T>
二,基本三要素
实现分页人所共知的三个基本属性:
DataSource :数据源,要知道数据源共计多少条数据,会对应一个数据源的方法- Count() , PageSize: 来描述每页显示的记录的条数。 PageIndex :当前页的索引值,一般第一页的索引值为0,当然为了表示方便,可以从1开始, 并且后面默认为从1开始。
// 分页数据源 public IEnumerable <T> DataSource { get ; private set ; } // 每页显示记录的数量 public int PageSize { get ; private set ; } // 当前页数 public int PageIndex { get ; set ; }
三,扩展属性
有了上述三要素,我们可以推论其他三个重要属性
// 分页总页数 public int PageCount { get ; private set ; } // 是否有前一页 public bool HasPrev { get { return PageIndex > 1 ; } } // 是否有下一页 public bool HasNext { get { return PageIndex < PageCount; } }
四,核心方法
最后就是需要实现分页的核心-获取分页数据的方法:
GetPagingData() :获取当页的数据,一般常用的手段是跳过 PageIndex*PageSize条记录,然后取 PageSize 条数据。 在.NET中有很多方法可以实现这一过程,这里介绍2个最简单的:
方法1,从序列的指定位置返回指定数量的连续元素:
public static IEnumerable <TSource> Take<TSource>( this IList <TSource> list, int start, int count ) { for ( int index = start; index < Math .Min( start + count, list.Count ); index++ ) { yield return list[index]; //yield关键字的用法大家可以参详其他文章 } }
那么我们的 GetPagingData() 方法就要这么写:
// 获取当前页数据 public IEnumerable <T> GetPagingData() { return DataSource.ToList<T> ().Take((PageIndex-1)× PageSize ,PageSize); }
其实我更倾向与第二种方法,就是使用 IEnumerable<T> 的扩展方法:
Skip(int count) :跳过序列中指定数量的元素,然后返回剩余的元素 Take(int count) :从序列的开头返回指定数量的连续元素。 那么我们的 GetPagingData() 只需要这么写就完事:
// 获取当前页数据 public IEnumerable<T> GetPagingData() { return DataSource.Skip((PageIndex - 1 ) * PageSize).Take(PageSize); }
这句代码就是跳过 PageIndex - 1 ) * PageSize 条数据 ,再取 PageSize 条数据 ,刚刚好就是我们需要的当前页的数据。
五,构造函数
实例化一个分页器的时候,我们需要对它进行初始化:
public PagingHelper( int pageSize, IEnumerable <T> dataSource) { this .PageSize = pageSize > 1 ? pageSize : 1 ; this .DataSource = dataSource; PageCount = ( int ) Math .Ceiling(dataSource.Count() / ( double )pageSize); }
真正的使用中,你可以重写分页器类,根据你的需要来控制哪些字段是只读的。比如你想随时改变页面元素的数量,那么你可以把PageSize设置为可读写的属性。
至此,这个分页器我们就完工拉。
六,与ASP.NET MVC的简单结合
首先我们通过VS创建一个空的基于Razor视图引擎的ASP.NET MVC3 Web应用程序,命名为JohnConnor.Web
对 创建过程 或Razor不太了解的看官,请移步 ASP.NET MVC Razor视图引擎攻略 <传送门> ,这里就不再赘述了。
然后我们需要进行以下几步
1,Models文件夹下,添加Student.cs文件,添加以下代码,为了演示方便这里模拟了一个数据源,实际中的数据源可能来自数据库。
public class Student { public int Id { get ; set ; } public string Name { get ; set ; } } public static class Students { public static IEnumerable<Student> data { get { return new List<Student> () { new Student{ Id= 0 , Name= " John " }, new Student{ Id= 1 , Name= " Marry " }, new Student{ Id= 2 , Name= " Andy " }, new Student{ Id= 3 , Name= " Tom " }, new Student{ Id= 4 , Name= " Lydia " }, new Student{ Id= 5 , Name= " Chris " }, new Student{ Id= 6 , Name= " Justin " }, new Student{ Id= 7 , Name= " Susan " } }; } } }
public class Student { public int Id { get ; set ; } public string Name { get ; set ; } } public static class Students { public static IEnumerable<Student> data { get { return new List<Student> () { new Student{ Id= 0 , Name= " John " }, new Student{ Id= 1 , Name= " Marry " }, new Student{ Id= 2 , Name= " Andy " }, new Student{ Id= 3 , Name= " Tom " }, new Student{ Id= 4 , Name= " Lydia " }, new Student{ Id= 5 , Name= " Chris " }, new Student{ Id= 6 , Name= " Justin " }, new Student{ Id= 7 , Name= " Susan " } }; } } }
2, Models文件夹下 ,添加PagingHelper.cs文件,添加我们上述分页器类。
public class PagingHelper<T> { // 分页数据源 public IEnumerable<T> DataSource { get ; private set ; } // 每页显示记录的数量 public int PageSize { get ; private set ; } // 当前页数 public int PageIndex { get ; set ; } // 分页总页数 public int PageCount { get ; private set ; } // 是否有前一页 public bool HasPrev { get { return PageIndex > 1 ; } } // 是否有下一页 public bool HasNext { get { return PageIndex < PageCount; } } // 构造函数 public PagingHelper( int pageSize, IEnumerable<T> dataSource) { this .PageSize = pageSize > 1 ? pageSize : 1 ; this .DataSource = dataSource; PageCount = ( int )Math.Ceiling(dataSource.Count() / ( double )pageSize); } // 获取当前页数据 public IEnumerable<T> GetPagingData() { return DataSource.Skip((PageIndex - 1 ) * PageSize).Take(PageSize); } }
public class PagingHelper<T> { // 分页数据源 public IEnumerable<T> DataSource { get ; private set ; } // 每页显示记录的数量 public int PageSize { get ; private set ; } // 当前页数 public int PageIndex { get ; set ; } // 分页总页数 public int PageCount { get ; private set ; } // 是否有前一页 public bool HasPrev { get { return PageIndex > 1 ; } } // 是否有下一页 public bool HasNext { get { return PageIndex < PageCount; } } // 构造函数 public PagingHelper( int pageSize, IEnumerable<T> dataSource) { this .PageSize = pageSize > 1 ? pageSize : 1 ; this .DataSource = dataSource; PageCount = ( int )Math.Ceiling(dataSource.Count() / ( double )pageSize); } // 获取当前页数据 public IEnumerable<T> GetPagingData() { return DataSource.Skip((PageIndex - 1 ) * PageSize).Take(PageSize); } }
3,在Controller文件夹下添加控制器命名为HomeController,添加以下代码。
public class HomeController : Controller { public ActionResult Index( int pageIndex= 1 ) { PagingHelper <Student> StudentPaging = new PagingHelper<Student>( 2 , Students.data); // 初始化分页器 StudentPaging.PageIndex = pageIndex; // 指定当前页 return View(StudentPaging); // 返回分页器实例到视图 } }
public class HomeController : Controller { public ActionResult Index( int pageIndex= 1 ) { PagingHelper <Student> StudentPaging = new PagingHelper<Student>( 2 , Students.data); // 初始化分页器 StudentPaging.PageIndex = pageIndex; // 指定当前页 return View(StudentPaging); // 返回分页器实例到视图 } }
4,在View文件夹下添加Home文件夹,并新增视图文件Index.cshtml,添加以下代码。
@using JohnConnor.Web.Models @model PagingHelper < Student > @{ ViewBag.Title = "Index"; } < h2 > Index </ h2 > @foreach (var Data in Model.GetPagingData()) { < p > ID:@Data.Id Name:@Data.Name </ p > } < p > @if (Model.HasPrev) { < a href ="@Url.Action(" Index", "Home", new { pageIndex = Model.PageIndex - 1 })" > 上一页 </ a > } else { < em style ="color:Gray" > 上一页 </ em > } @if (Model.HasNext) { < a href ="@Url.Action(" Index", "Home", new { pageIndex = Model.PageIndex + 1 })" > 下一页 </ a > } else { < em style ="color:Gray" > 下一页 </ em > } </ p >
@using JohnConnor.Web.Models @model PagingHelper < Student > @{ ViewBag.Title = "Index"; } < h2 > Index </ h2 > @foreach (var Data in Model.GetPagingData()) { < p > ID:@Data.Id Name:@Data.Name </ p > } < p > @if (Model.HasPrev) { < a href ="@Url.Action(" Index", "Home", new { pageIndex = Model.PageIndex - 1 })" > 上一页 </ a > } else { < em style ="color:Gray" > 上一页 </ em > } @if (Model.HasNext) { < a href ="@Url.Action(" Index", "Home", new { pageIndex = Model.PageIndex + 1 })" > 下一页 </ a > } else { < em style ="color:Gray" > 下一页 </ em > } </ p >
5,在Global.asax中配置路由,我们修改一下默认路由就可以了。
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{pageIndex}", // 带有参数的 URL new { controller = "Home", action = "Index", pageIndex = UrlParameter.Optional } // 参数默认值 ); }
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // 路由名称 "{controller}/{action}/{pageIndex}", // 带有参数的 URL new { controller = "Home", action = "Index", pageIndex = UrlParameter.Optional } // 参数默认值 ); }
现在保存之后F5运行,就可以看到一个简单的分页程序了。
而变成了http://localhost:1234/Home/Index/1 这样的静态URL,更简洁,更美观。
---------------------------------------End---------------------------------------
这篇中的提到分页器,只是一个很简易的分页思想的实现,其实本身的性能还是有待提高的。
希望能抛砖引玉,哪位大神能分享出性能更强大的分页程序。
文章中最后提到了URL重写与优化,如果看官们有兴趣,可以参见我之前的文章:
ASP.NET MVC URL重写与优化(初级篇)-使用Global路由表定制URL
ASP.NET MVC URL重写与优化(进阶篇)-继承RouteBase玩转URL
分类: ASP.NET MVC
标签: ASP.NET MVC
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息