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"} }; } } }
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); } }
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);//返回分頁器實例到視圖 } }
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>
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 } // 參數默認值 ); }
ASP.NET MVC 簡單的分頁思想與實現