zoukankan      html  css  js  c++  java
  • asp.net mvc 简易通用自定义Pager实现分页

    asp.net mvc 自定义Pager实现分页

    Intro

    一个WEB应用程序中经常会用到数据分页,本文将实现一个简单通用的分页组件,包含一个 PagerModel (用来保存页码信息),一个 HtmlHelperPager 扩展方法和一个 PagedListModel<T> 分页数据模型。

    pager效果图如下:

    pager

    PagerModel 分页模型

    PagerModel 用来保存分页信息,代码实现如下:

     1     /// <summary>
     2     /// PagerModel 分页模型
     3     /// </summary>
     4     public class PagerModel
     5     {
     6         public int PageIndex { get; set; }
     7 
     8         public int PageSize { get; set; }
     9 
    10         public int PageCount { get; private set; }
    11 
    12         public int TotalCount { get; set; }
    13 
    14         public PagerModel(int totalCount)
    15         {
    16             PageIndex = 1;
    17             PageSize = 10;
    18             TotalCount = totalCount;
    19             PageCount = Convert.ToInt32(Math.Ceiling(TotalCount * 1.0 / PageSize));
    20         }
    21 
    22         public PagerModel(int pageSize, int totalCount)
    23         {
    24             PageIndex = 1;
    25             PageSize = pageSize;
    26             TotalCount = totalCount;
    27             PageCount = Convert.ToInt32(Math.Ceiling(TotalCount * 1.0 / PageSize));
    28         }
    29 
    30         public PagerModel(int pageIndex, int pageSize, int totalCount)
    31         {
    32             PageIndex = pageIndex;
    33             PageSize = pageSize;
    34             TotalCount = totalCount;
    35             PageCount = Convert.ToInt32(Math.Ceiling(TotalCount * 1.0 / PageSize));
    36         }
    37     }
    PagerModel
      /// <summary>
      /// PagerModel 分页模型
      /// </summary>
      public class PagerModel
      {
          public int PageIndex { get; set; }
    
          public int PageSize { get; set; }
    
          public int PageCount { get; private set; }
    
          public int TotalCount { get; set; }
    
          public PagerModel(int totalCount)
          {
              PageIndex = 1;
              PageSize = 10;
              TotalCount = totalCount;
              PageCount = Convert.ToInt32(Math.Ceiling(TotalCount * 1.0 / PageSize));
          }
    
          public PagerModel(int pageSize, int totalCount)
          {
              PageIndex = 1;
              PageSize = pageSize;
              TotalCount = totalCount;
              PageCount = Convert.ToInt32(Math.Ceiling(TotalCount * 1.0 / PageSize));
          }
    
          public PagerModel(int pageIndex, int pageSize, int totalCount)
          {
              PageIndex = pageIndex;
              PageSize = pageSize;
              TotalCount = totalCount;
              PageCount = Convert.ToInt32(Math.Ceiling(TotalCount * 1.0 / PageSize));
          }
      }
    

    Pager扩展方法

    Pager扩展方法 可根据自己的需求进行定制话实现,Pager扩展方法需要一个PagerModel类型的参数来生成页码,我这里是用的bootstrap的样式来做的分页,整个系统用的是同一个样式的分页所以把样式直接写死在代码里了。
    Pager这里的代码重构做的不是太好:

    •  样式直接写死,前端不好维护
     1     /// <summary>
     2     /// PagerHelper 分页帮助类
     3     /// </summary>
     4     public static class PagerHelper
     5     {
     6         public static MvcHtmlString Pager(this HtmlHelper helper, PagerModel pager)
     7         {
     8             StringBuilder sbHtmlText = new StringBuilder();
     9             sbHtmlText.Append("<div style="text-align:center"><nav><ul  class="pagination">");
    10             if (pager.PageIndex <= 1)
    11             {
    12                 sbHtmlText.Append("<li class="disabled"><a href="javascript:void()" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>");
    13             }
    14             else
    15             {
    16                 sbHtmlText.AppendFormat("<li><a href="javascript:loadData(1)" aria-label="1"><span aria-hidden="true">&laquo;</span></a></li>", pager.PageIndex - 1);
    17                 sbHtmlText.AppendFormat("<li><a href="javascript:loadData({0})">{0}</a></li>", pager.PageIndex - 1);
    18             }
    19             sbHtmlText.AppendFormat("<li class="active"><a href="javascript:void()">{0}<span class="sr-only">(current)</span></a></li>", pager.PageIndex);
    20             if (pager.PageIndex >= pager.PageCount)
    21             {
    22                 sbHtmlText.Append("<li class="disabled"><a href="javascript:void()" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>");
    23             }
    24             else
    25             {
    26                 sbHtmlText.AppendFormat("<li><a href="javascript:loadData({0})">{0}</a></li>", pager.PageIndex + 1);
    27                 sbHtmlText.AppendFormat("<li><a href="javascript:loadData({0})" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>", pager.PageIndex + 1);
    28             }
    29             sbHtmlText.Append("</ul></nav>");
    30             sbHtmlText.AppendFormat("<div><span>每页有<strong>{0}</strong>条数据,一共有<strong>{1}</strong>页,总计<strong>{2}</strong>条数据</span></div></div>", pager.PageSize, pager.PageCount, pager.TotalCount);            
    31             return MvcHtmlString.Create(sbHtmlText.ToString());
    32         }
    33 
    34         public static MvcHtmlString Pager(this HtmlHelper helper, PagerModel pager, Func<int, string> onPageChange)
    35         {
    36             StringBuilder sbHtmlText = new StringBuilder();
    37             sbHtmlText.Append("<div style="text-align:center"><nav><ul  class="pagination">");
    38             if (pager.PageIndex <= 1)
    39             {
    40                 sbHtmlText.Append("<li class="disabled"><a href="javascript:void()" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>");
    41             }
    42             else
    43             {
    44                 sbHtmlText.AppendFormat("<li><a href="{0}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>", onPageChange(pager.PageIndex - 1));
    45                 sbHtmlText.AppendFormat("<li><a href="{0}">{1}</a></li>", onPageChange(pager.PageIndex - 1), pager.PageIndex - 1);
    46             }
    47             sbHtmlText.AppendFormat("<li class="active"><a href="javascript:void()">{0}<span class="sr-only">(current)</span></a></li>", pager.PageIndex);
    48             if (pager.PageIndex >= pager.PageCount)
    49             {
    50                 sbHtmlText.Append("<li class="disabled"><a href="javascript:void()" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>");
    51             }
    52             else
    53             {
    54                 sbHtmlText.AppendFormat("<li><a href="{0}">{1}</a></li>", onPageChange(pager.PageIndex+1),pager.PageIndex + 1);
    55                 sbHtmlText.AppendFormat("<li><a href="{0}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>", onPageChange(pager.PageIndex + 1));
    56             }
    57             sbHtmlText.Append("</ul></nav>");
    58             sbHtmlText.AppendFormat("<div><span>每页有<strong>{0}</strong>条数据,一共有<strong>{1}</strong>页,总计<strong>{2}</strong>条数据</span></div></div>", pager.PageSize, pager.PageCount, pager.TotalCount);
    59             return MvcHtmlString.Create(sbHtmlText.ToString());
    60         }
    61     }
    PagerHelper
      /// <summary>
      /// PagerHelper 分页帮助类
      /// </summary>
      public static class PagerHelper
      {
          public static MvcHtmlString Pager(this HtmlHelper helper, PagerModel pager)
          {
              StringBuilder sbHtmlText = new StringBuilder();
              sbHtmlText.Append("<div style="text-align:center"><nav><ul class="pagination">");
              if (pager.PageIndex <= 1)
              {
                  sbHtmlText.Append("<li class="disabled"><a href="javascript:void()" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>");
              }
              else
              {
                  sbHtmlText.AppendFormat("<li><a href="javascript:loadData({0})" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>", pager.PageIndex - 1);
                  sbHtmlText.AppendFormat("<li><a href="javascript:loadData({0})">{0}</a></li>", pager.PageIndex - 1);
              }
              sbHtmlText.AppendFormat("<li class="active"><a href="javascript:void()">{0}<span class="sr-only">(current)</span></a></li>", pager.PageIndex);
              if (pager.PageIndex >= pager.PageCount)
              {
                  sbHtmlText.Append("<li class="disabled"><a href="javascript:void()" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>");
              }
              else
              {
                  sbHtmlText.AppendFormat("<li><a href="javascript:loadData({0})">{0}</a></li>", pager.PageIndex + 1);
                  sbHtmlText.AppendFormat("<li><a href="javascript:loadData({0})" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>", pager.PageIndex + 1);
              }
              sbHtmlText.Append("</ul></nav>");
              sbHtmlText.AppendFormat("<div><span>每页有<strong>{0}</strong>条数据,一共有<strong>{1}</strong>页,总计<strong>{2}</strong>条数据</span></div></div>", pager.PageSize, pager.PageCount, pager.TotalCount);            
              return MvcHtmlString.Create(sbHtmlText.ToString());
          }
      }
    

    利用 Func<> 简单重构了一下代码,可以自定义翻页事件

       public static MvcHtmlString Pager(this HtmlHelper helper, PagerModel pager, Func<int, string> onPageChange)
       {
           StringBuilder sbHtmlText = new StringBuilder();
           sbHtmlText.Append("<div style="text-align:center"><nav><ul  class="pagination">");
           if (pager.PageIndex <= 1)
           {
               sbHtmlText.Append("<li class="disabled"><a href="javascript:void()" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>");
           }
           else
           {
               sbHtmlText.AppendFormat("<li><a href="{0}" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>", onPageChange(pager.PageIndex - 1));
               sbHtmlText.AppendFormat("<li><a href="{0}">{1}</a></li>", onPageChange(pager.PageIndex - 1), pager.PageIndex - 1);
           }
           sbHtmlText.AppendFormat("<li class="active"><a href="javascript:void()">{0}<span class="sr-only">(current)</span></a></li>", pager.PageIndex);
           if (pager.PageIndex >= pager.PageCount)
           {
               sbHtmlText.Append("<li class="disabled"><a href="javascript:void()" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>");
           }
           else
           {
               sbHtmlText.AppendFormat("<li><a href="{0}">{1}</a></li>", onPageChange(pager.PageIndex+1),pager.PageIndex + 1);
               sbHtmlText.AppendFormat("<li><a href="{0}" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>", onPageChange(pager.PageIndex + 1));
           }
           sbHtmlText.Append("</ul></nav>");
           sbHtmlText.AppendFormat("<div><span>每页有<strong>{0}</strong>条数据,一共有<strong>{1}</strong>页,总计<strong>{2}</strong>条数据</span></div></div>", pager.PageSize, pager.PageCount, pager.TotalCount);
           return MvcHtmlString.Create(sbHtmlText.ToString());
       }
    

    关于样式修改维护的问题,找到一种解决方案,可以将分页代码的样式封装在一个分部视图partial,在需要分页的页面视图,引用这个分部视图并且将分页模型信息 PagerModel 传递给这个分部视图

    PagedListModel 分页数据模型

    PagedListModel 用来封装返回到视图 View 的数据和 分页模型 PagerModel,实现代码如下

     1     /// <summary>
     2     /// 数据分页模型
     3     /// </summary>
     4     /// <typeparam name="T">数据类型</typeparam>
     5     public class PagedListModel<T> where T : class, new()
     6     {
     7         public List<T> Data { get; set; }
     8 
     9         public PagerModel Pager { get; set; }
    10     }
    PagedListModel
      public class PagedListModel<T> where T : class, new()
      {
          public List<T> Data { get; set; }
    
          public PagerModel Pager { get; set; }
      }
    

    控制器数据处理

    控制器处理代码如下:
    search 是一个包含了 PageIndex 和 PageSize 的请求参数

     1             int rowsCount = 0;
     2             try
     3             {
     4                 List<Models.BlockEntity> blockList = BusinessHelper.BlockEntityHelper.GetPagedList(search.PageIndex, search.PageSize, out rowsCount, whereLambda, b => b.BlockTime, false);
     5                 PagerModel pager = new PagerModel(search.PageIndex, search.PageSize, rowsCount);
     6                 PagedListModel<Models.BlockEntity> dataList = new PagedListModel<Models.BlockEntity>() { Pager = pager, Data = blockList };
     7                 return View(dataList);
     8             }
     9             catch (Exception ex)
    10             {
    11                 logger.Error(ex);
    12                 throw;
    13             }
    Controller
           int rowsCount = 0;
           try
           {
               List<Models.BlockEntity> blockList = new Business.BLLBlockEntity().GetPagedList(search.PageIndex, search.PageSize, out rowsCount, whereLambda, b => b.BlockTime, false);//记录日志
               PagerModel pager = new PagerModel(search.PageIndex, search.PageSize, rowsCount);//定义Pager Model
               PagedListModel<Models.BlockEntity> dataList = new PagedListModel<Models.BlockEntity>() { Pager = pager, Data = blockList };//定义返回到 View 的 PagedListModel
               return View(dataList);
           }
           catch (Exception ex)
           {
               logger.Error(ex);//记录日志
               throw;
           }
    

    页面处理

    首先在页面顶部声明 model 模型

      @model PagedListModel<Models.BlockEntity>
    

    在页面上遍历数据

      @foreach (Models.BlockEntity item in Model.Data)
    

    在需要添加分页信息的地方使用 HtmlHelper 的 Pager 扩展方法

      @Html.Pager(Model.Pager)
    

    View代码示例

     1 @model PagedListModel<Models.BlockEntity>
     2 <table class="table table-hover">
     3     <thead>
     4         <tr>
     5             <th>黑名单类型</th>
     6             <th>黑名单内容</th>
     7             <th>拉入黑名单时间</th>
     8             <th>状态</th>
     9             <th>操作</th>
    10         </tr>
    11     </thead>
    12     <tbody>
    13         @foreach (Models.BlockEntity item in Model.Data)
    14         {
    15             string className = "bg-success";
    16             if (!item.IsActive)
    17             {
    18                 className = "bg-danger";
    19             }
    20              <tr class="@className">
    21                     <td>
    22                         @item.BlockType.TypeName
    23                     </td>
    24                     <td>
    25                         @item.BlockValue
    26                     </td>
    27                     <td>
    28                         @item.BlockTime
    29                     </td>
    30                     <td>
    31                         @if (item.IsActive)
    32                     {
    33                             <span>启用</span>
    34                         }
    35                         else
    36                         {
    37                             <span>禁用</span>
    38                         }
    39                     </td>
    40                     <td>
    41                         @if (item.IsActive)
    42                     {
    43                             <button type="button" class='btn btn-warning' onclick="UpdateStatus('@item.BlockId', '@item.BlockValue',-1,this)">禁用</button>
    44                         }
    45                         else
    46                         {
    47                             <button type="button" class='btn btn-warning' onclick="UpdateStatus('@item.BlockId','@item.BlockValue',1,this)">启用</button>
    48                         }
    49                         <button type="button" class="btn btn-danger" onclick="DeleteEntity('@item.BlockId','@item.BlockValue',this)">删除</button>
    50                     </td>
    51                 </tr>
    52             }
    53     </tbody>
    54 </table>
    55 @Html.Pager(Model.Pager)
  • 相关阅读:
    2月11日
    亚特兰蒂斯
    080215 晴
    2月9日
    2月6日
    2月10日
    080208 晴(0,50)
    关于春晚
    (15,50)
    恍然大悟
  • 原文地址:https://www.cnblogs.com/weihanli/p/simplePagerInAspNetMvc.html
Copyright © 2011-2022 走看看