好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

MVC 简单的分页思想与实现

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 ; }

  

三,扩展属性

  有了上述三要素,我们可以推论其他三个重要属性

PageCount :总页数,其值取大于或等于  DataSource.Count/PageSize 的最小整数 ,比如5.2页,其实就是6页。 HasPrev :用来判断是否有上一页,如果索引 PageIndex 从1开始,那就是判断 PageIndex > 1 是否成立 。 HasNext :用力判断是否有下一页,如果索引  PageIndex  从1开始,需判断 PageIndex < PageCount 是否成立。

 //  分页总页数 
 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/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于MVC 简单的分页思想与实现的详细内容...

  阅读:41次