请选择 进入手机版 | 继续访问电脑版
查看: 519|回复: 0

[.NET源码] ASP.net MVC4自己打造分页Pager实例代码 (数字版,Ajax)

3万

主题

3万

帖子

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
100197
发表于 2015-11-19 18:24:06

前言
用ASP.net MVC开发网站真的要写很多javascript

这时就很感谢之前自己待过Java Team,有写过JSP的经验,运用到ASP.net MVC这边XD

看了一下网路上关于资料分页这块,很多人都分享现成的分页元件解决方案,自己手写打造的范例程式码还满少见

用现成元件好处是功能马上做好

缺点是若要套美工人员设计的版,比较没有弹性

而且万一被客户发现:咦?这个分页样式好像跟当初确认的版型不一样…,就GG了,呵呵

为了避免有网友重蹈我的覆彻,把分页底层的程式码公开,数字Ajax版

下拉选单版(页数都塞进下拉选单里),等有空再补完,不过若会数字版的原理,下拉选单版应该不是问题

我觉得比较困难的是计算切换数字群组部份,有比此篇文章更好公式的话,麻烦请提出,先谢啰~

说明都在注解里


实例
Model资料夹

准备Html Table要呈现的资料类别

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. namespace MvcApplicationPager.Models
  6. {
  7. public class ProductViewModel
  8. {
  9. /// <summary>
  10. /// 编号
  11. /// </summary>
  12. public int No { get; set; }
  13. /// <summary>
  14. /// 名称
  15. /// </summary>
  16. public string ProductName { get; set; }
  17. /// <summary>
  18. /// 是否上下架
  19. /// </summary>
  20. public bool IsOpen { get; set; }
  21. }
  22. }
复制代码

Global.asax.cs塞假资料

  1. using MvcApplicationPager.Models;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Web;
  6. using System.Web.Http;
  7. using System.Web.Mvc;
  8. using System.Web.Routing;
  9. namespace MvcApplicationPager
  10. {
  11. // Note: For instructions on enabling IIS6 or IIS7 classic mode,
  12. // visit http://go.microsoft.com/?LinkId=9394801
  13. public class MvcApplication : System.Web.HttpApplication
  14. {
  15. //假装这是DB捞出来的资料
  16. public static List<ProductViewModel> dbList = new List<ProductViewModel>();
  17. protected void Application_Start()
  18. {
  19. AreaRegistration.RegisterAllAreas();
  20. #region 塞假资料
  21. Random rand = new Random(Guid.NewGuid().GetHashCode());
  22. for (int i = 1; i <= 104; i++)
  23. {
  24. bool IsOpen = true;//Default
  25. int number = rand.Next(1, 3);//1~2
  26. if (number == 2)
  27. {
  28. IsOpen = false;
  29. }
  30. dbList.Add(new ProductViewModel()
  31. {
  32. No = i,
  33. ProductName = Guid.NewGuid().ToString().Substring(0, 5).ToUpper(),
  34. IsOpen = IsOpen
  35. });
  36. }
  37. #endregion
  38. WebApiConfig.Register(GlobalConfiguration.Configuration);
  39. FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
  40. RouteConfig.RegisterRoutes(RouteTable.Routes);
  41. }
  42. }
  43. }
复制代码

HomeController.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.Mvc;
  6. //刚刚宣告的
  7. using MvcApplicationPager.Models;
  8. using System.Text;
  9. namespace MvcApplicationPager.Controllers
  10. {
  11. public class HomeController : Controller
  12. {
  13. [HttpGet]
  14. public ActionResult Index()
  15. {
  16. //上下架的下拉选单的资料清单
  17. ViewData["IsOpenItems"] = new List<SelectListItem>()
  18. {
  19. new SelectListItem(){ Text="请选择",Value="-1",Selected=true},
  20. new SelectListItem(){ Text="上架",Value="true" },
  21. new SelectListItem(){ Text="下架",Value="false" },
  22. };
  23. IEnumerable<ProductViewModel> result = this.QueryData(10, 0, new FormCollection());
  24. return View(result);
  25. }
  26. /// <summary>
  27. /// 查询资料
  28. /// </summary>
  29. /// <returns></returns>
  30. public IEnumerable<ProductViewModel> QueryData(int iPageSize, int iCurrentPageIndex, FormCollection form)
  31. {
  32. var result = from r in MvcApplication.dbList
  33. select r;
  34. if (!string.IsNullOrEmpty(form["sProductName"]))
  35. {//有输入名称
  36. result = from r in result
  37. where r.ProductName.Contains(form["sProductName"])
  38. select r;
  39. }
  40. //有输入上下架
  41. if (form["sIsOpen"] != null && form["sIsOpen"] != "-1")
  42. {
  43. result = from r in result
  44. where r.IsOpen == Convert.ToBoolean(form["sIsOpen"])
  45. select r;
  46. }
  47. //部份检视要显示TempData["pager"]
  48. TempData["pager"] = this.pageString(result,iPageSize,iCurrentPageIndex);
  49. //抓DB少量的资料
  50. result = result.Skip(iCurrentPageIndex * iPageSize).Take(iPageSize);
  51. return result;
  52. }
  53. /// <summary>
  54. /// 产生pager字串(这个请再自行抽到其他Utility之类的类别里)
  55. /// </summary>
  56. /// <param name="result">集合物件</param>
  57. /// <param name="iPageSize">每页显示几笔</param>
  58. /// <param name="iCurrentPageIndex">目前的索引页</param>
  59. /// <returns></returns>
  60. public string pageString(IEnumerable<object> result,int iPageSize,int iCurrentPageIndex)
  61. {
  62. #region Pager处理(文章重点在这!)
  63. //总笔数
  64. int iRowTotal = result.Count();
  65. //总页数
  66. int iPageTotal = (iRowTotal / iPageSize);
  67. if (iRowTotal % iPageSize > 0)
  68. {
  69. iPageTotal++;
  70. }
  71. //目前页数
  72. int iCurrentPage = iCurrentPageIndex + 1;
  73. //防呆
  74. if (iCurrentPage > iPageTotal)
  75. {
  76. iCurrentPage = iPageTotal;
  77. iCurrentPageIndex = iCurrentPage - 1;
  78. }
  79. if (iCurrentPage < 0)
  80. {
  81. iCurrentPage = 1;
  82. iCurrentPageIndex = 0;
  83. }
  84. //页数字按钮每5个一组呈现(这边可自行更改)
  85. int pNumber = 5;
  86. //页数字按钮共被分为几分
  87. int ppSize = iPageTotal / pNumber;
  88. if (iPageTotal % pNumber > 0)
  89. {
  90. ppSize++;
  91. }
  92. //目前在哪一份(从1算起),为了显示「...」
  93. int currentPPSize = (iCurrentPageIndex / pNumber) + 1;
  94. //要回传的字串
  95. StringBuilder sb = new StringBuilder();
  96. //第二页以后才有上一页
  97. string strPreJS = ((iCurrentPage > 1) ? "javascript:search('" + (iCurrentPage - 1) + "');" : "#");
  98. sb.Append("<a href="" + strPreJS + "">← Prev</a>");
  99. sb.Append("<a href="javascript:search(1);">First</a>");
  100. //这公式算了我好久...Orz
  101. int pStart = ((iCurrentPageIndex / pNumber) * pNumber + 1);
  102. int pEnd = pStart + (pNumber - 1);
  103. if (pEnd > iPageTotal)
  104. {
  105. pEnd = iPageTotal;
  106. }
  107. if (currentPPSize > 1)
  108. {
  109. sb.Append("<a href="javascript:search('" + (pStart - 1) + "')">...</a>");
  110. }
  111. //产生页数按钮(从1算起)
  112. for (int i = pStart; i <= pEnd; i++)
  113. {
  114. //复制范例时候,class="highColor"可以删除
  115. sb.Append("<a class='"+(i==iCurrentPage?"highColor":"")+"' href="javascript:search('" + i + "');">" + i + "</a>");
  116. }
  117. if ((currentPPSize < ppSize))
  118. {
  119. sb.Append("<a href="javascript:search('" + (pEnd + 1) + "');">...</a>");
  120. }
  121. //目前页小于最后一页,就有下一页按钮
  122. string strNextJS = (iCurrentPage < iPageTotal ? "javascript:search('" + (iCurrentPage + 1) + "');" : "#");
  123. sb.Append("<a href="javascript:search(" + iPageTotal + ");">Last</a>");
  124. sb.Append("<a href="" + strNextJS + "">Next → </a>");
  125. #endregion
  126. return sb.ToString();
  127. }
  128. /// <summary>
  129. /// Ajax查询资料
  130. /// </summary>
  131. /// <param name="iPageSize"></param>
  132. /// <param name="iCurrentPageIndex"></param>
  133. /// <returns></returns>
  134. [HttpPost]
  135. public ActionResult ActionQueryData(FormCollection form)
  136. {
  137. //这里的int iPageSize, int iCurrentPageIndex参数,前端使用者可能会用F12开发者工具乱改成字串
  138. //怎么防御就请自由料理了...
  139. int iPageSize = Convert.ToInt32(form["hPageSize"]);
  140. int iCurrentPageIndex = Convert.ToInt32(form["hCurrentPageIndex"]);
  141. IEnumerable<ProductViewModel> result = this.QueryData(iPageSize, iCurrentPageIndex, form);
  142. return View("HtmlTable", result);
  143. }
  144. }
  145. }
复制代码

View的Index.cshtml

读取中效果有使用到jQuery Block UI

官网:http://www.malsup.com/jquery/block/

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta name="viewport" content="width=device-width" />
  5. <title>Index</title>
  6. <script type="text/javascript" src="@Url.Content("~/Scripts/jquery-2.0.0.min.js")"></script>
  7. <script type="text/javascript" src="http://malsup.github.com/jquery.blockUI.js"></script>
  8. <script type="text/javascript">
  9. //清除画面上的hidden www.it165.net
  10. function clearHidden() {
  11. $("input[name='hPageSize']").val("");
  12. $("input[name='hCurrentPageIndex']").val("");
  13. }
  14. //Ajax查询
  15. function search(pageNumber) {
  16. //要block哪个元素这边自由料理
  17. $("form[name='myForm']").block({
  18. message: '<h1>读取中...</h1>',
  19. css: { border: '3px solid #a00' }
  20. });
  21. //每页显示几笔
  22. var pageSize = $("#selectPageSize").val();
  23. $("input[name='hPageSize']").val(pageSize);
  24. //目前页索引
  25. $("input[name='hCurrentPageIndex']").val((pageNumber - 1));
  26. var myForm = $("form[name='myForm']").serialize();
  27. $.ajax({
  28. url: "@Url.Action("ActionQueryData", "Home")",
  29. type: "post",
  30. async: true,
  31. data: myForm,
  32. success: function (result) {
  33. //先清除上一次的结果
  34. $("#divHtmlTable").empty();
  35. //更新Html Table
  36. $("#divHtmlTable").html(result);
  37. //hidden都清掉,避免影响下一次的查询结果
  38. clearHidden();
  39. //解除block UI
  40. $("form[name='myForm']").unblock();
  41. },
  42. error: function (xhr) {
  43. //hidden都清掉,避免影响下一次的查询结果
  44. clearHidden();
  45. //显示错误讯息
  46. alert(xhr.responseText);
  47. }
  48. });
  49. }
  50. </script>
  51. </head>
  52. <body>
  53. @using (Html.BeginForm("", "", FormMethod.Post, new { name="myForm"}))
  54. {
  55. @Html.Hidden("hPageSize")
  56. @Html.Hidden("hCurrentPageIndex")
  57. @*查询输入条件,要放在更新区块外面*@
  58. <div>
  59. 名称:@Html.TextBox("sProductName")<br />
  60. 上下架:@Html.DropDownList("sIsOpen",(IEnumerable<SelectListItem>)ViewData["IsOpenItems"] )<br />
  61. 每页显示几笔:@Html.DropDownList("selectPageSize", new List<SelectListItem>() {
  62. new SelectListItem(){ Text="10",Value="10",Selected=true},
  63. new SelectListItem(){ Text="30",Value="30"},
  64. new SelectListItem(){ Text="50",Value="50"},
  65. } )
  66. @*按下搜寻后,到搜寻结果第1页*@
  67. <input type="button" value="搜寻" onclick="search(1);" /><br />
  68. </div>
  69. @*要更新的Html Table和Pager
  70. 为了Ajax的callback function方便更新画面上的Table,把Table和Pager包成部份检视*@
  71. <div id="divHtmlTable">
  72. @Html.Partial("HtmlTable",Model)
  73. </div>
  74. }
  75. </body>
  76. </html>
复制代码

部份检视的HtmlTable.cshtml

  1. @model IEnumerable<MvcApplicationPager.Models.ProductViewModel>
  2. @*复制范例时候,这个css可以删除*@
  3. <style type="text/css">
  4. /*让pager各数字间有空隔*/
  5. #divPager a {
  6. margin:2px;
  7. }
  8. /*目前页数字的背景颜色*/
  9. .highColor
  10. {
  11. background-color:red;
  12. }
  13. </style>
  14. <table cellspacing="0" cellpadding="0" border="1" >
  15. <thead>
  16. <tr >
  17. <th>编号</th>
  18. <th>名称</th>
  19. <th>上下架</th>
  20. </tr>
  21. </thead>
  22. <tbody >
  23. @foreach (var item in Model)
  24. {
  25. <tr>
  26. <td>@item.No</td>
  27. <td>@item.ProductName</td>
  28. <td>@item.IsOpen</td>
  29. </tr>
  30. }
  31. </tbody>
  32. </table><br />
  33. @*分页*@
  34. <div id="divPager">
  35. @Html.Raw(TempData["pager"])
  36. </div>
复制代码

执行画面:


画面弄得很阳春,这样才好套美工人员的设计版型

结语:
大概这样,剩下参数的验证检查就再自行补完吧



回复

使用道具 举报