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

Intro

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

pager效果图如下:

PagerModel 分页模型

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 = ;
PageSize = ;
TotalCount = totalCount;
PageCount = Convert.ToInt32(Math.Ceiling(TotalCount * 1.0 / PageSize));
} public PagerModel(int pageSize, int totalCount)
{
PageIndex = ;
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));
}
}

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这里的代码重构做的不是太好:

  • 样式直接写死,前端不好维护
     /// <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 <= )
{
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(1)\" aria-label=\"1\"><span aria-hidden=\"true\">&laquo;</span></a></li>", pager.PageIndex - );
sbHtmlText.AppendFormat("<li><a href=\"javascript:loadData({0})\">{0}</a></li>", pager.PageIndex - );
}
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 + );
sbHtmlText.AppendFormat("<li><a href=\"javascript:loadData({0})\" aria-label=\"Next\"><span aria-hidden=\"true\">&raquo;</span></a></li>", pager.PageIndex + );
}
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());
} 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 <= )
{
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 - ));
sbHtmlText.AppendFormat("<li><a href=\"{0}\">{1}</a></li>", onPageChange(pager.PageIndex - ), pager.PageIndex - );
}
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+),pager.PageIndex + );
sbHtmlText.AppendFormat("<li><a href=\"{0}\" aria-label=\"Next\"><span aria-hidden=\"true\">&raquo;</span></a></li>", onPageChange(pager.PageIndex + ));
}
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());
}
}

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,实现代码如下

     /// <summary>
/// 数据分页模型
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
public class PagedListModel<T> where T : class, new()
{
public List<T> Data { get; set; } public PagerModel Pager { get; set; }
}

PagedListModel

  public class PagedListModel<T> where T : class, new()
{
public List<T> Data { get; set; } public PagerModel Pager { get; set; }
}

控制器数据处理

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

             int rowsCount = ;
try
{
List<Models.BlockEntity> blockList = BusinessHelper.BlockEntityHelper.GetPagedList(search.PageIndex, search.PageSize, out rowsCount, whereLambda, b => b.BlockTime, false);
PagerModel pager = new PagerModel(search.PageIndex, search.PageSize, rowsCount);
PagedListModel<Models.BlockEntity> dataList = new PagedListModel<Models.BlockEntity>() { Pager = pager, Data = blockList };
return View(dataList);
}
catch (Exception ex)
{
logger.Error(ex);
throw;
}

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代码示例

 @model PagedListModel<Models.BlockEntity>
<table class="table table-hover">
<thead>
<tr>
<th>黑名单类型</th>
<th>黑名单内容</th>
<th>拉入黑名单时间</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
@foreach (Models.BlockEntity item in Model.Data)
{
string className = "bg-success";
if (!item.IsActive)
{
className = "bg-danger";
}
<tr class="@className">
<td>
@item.BlockType.TypeName
</td>
<td>
@item.BlockValue
</td>
<td>
@item.BlockTime
</td>
<td>
@if (item.IsActive)
{
<span>启用</span>
}
else
{
<span>禁用</span>
}
</td>
<td>
@if (item.IsActive)
{
<button type="button" class='btn btn-warning' onclick="UpdateStatus('@item.BlockId', '@item.BlockValue',-1,this)">禁用</button>
}
else
{
<button type="button" class='btn btn-warning' onclick="UpdateStatus('@item.BlockId','@item.BlockValue',1,this)">启用</button>
}
<button type="button" class="btn btn-danger" onclick="DeleteEntity('@item.BlockId','@item.BlockValue',this)">删除</button>
</td>
</tr>
}
</tbody>
</table>
@Html.Pager(Model.Pager)

asp.net mvc 简易通用自定义Pager实现分页的更多相关文章

  1. ASP.NET MVC如何实现自定义验证(服务端验证+客户端验证)

    ASP.NET MVC通过Model验证帮助我们很容易的实现对数据的验证,在默认的情况下,基于ValidationAttribute的声明是验证被使用,我们只需 要将相应的ValidationAttr ...

  2. asp.net mvc Route 使用自定义条件(constraints)禁止某ip登陆

    asp.net mvc Route 使用自定义条件(constraints)禁止某ip登陆 前言 本文的目的是利用Mvc route创建一个自定义约束来控制路由跳转实现禁止ip登陆,当然例子可能不合理 ...

  3. 让Asp.net mvc WebAPI 支持OData协议进行分页查询操作

    这是我在用Asp.net mvc WebAPI 支持 OData协议 做分页查询服务时的 个人拙笔. 代码已经开发到oschina上.有兴趣的朋友可以看看,欢迎大家指出不足之处. 看过了园子里的几篇关 ...

  4. 在 ASP.NET MVC 中创建自定义 HtmlHelper

    在ASP.NET MVC应用程序的开发中,我们常碰到类似Html.Label或Html.TextBox这样的代码,它将在网页上产生一个label或input标记.这些HtmlHelper的扩展方法有些 ...

  5. 在ASP.NET MVC 3 中自定义AuthorizeAttribute时需要注意的页面缓存问题

    一.ASP.NET MVC中使用OutputCache实现服务器端页面级缓存 在ASP.NET MVC中,假如我们想要将某个页面(即某个Action)缓存在服务器端,可以在Action上标上以下特性: ...

  6. asp.net mvc 中的自定义验证(Custom Validation Attribute)

    前言

  7. asp.net mvc简单实现基于Razor的分页控件

    最近在写一些web应用了解了一下asp.net mvc发现的确好用,所以直接就干上了.不过在使用asp.net mvc的Razor模板的情况并不向传统webform那样可以使用控件.但从Razor的功 ...

  8. asp.net MVC helper 和自定义函数@functions小结

    asp.net Razor 视图具有.cshtml后缀,可以轻松的实现c#代码和html标签的切换,大大提升了我们的开发效率.但是Razor语法还是有一些棉花糖值得我们了解一下,可以更加强劲的提升我们 ...

  9. [转]asp.net MVC helper 和自定义函数@functions小结

    本文转自:http://www.cnblogs.com/jiagoushi/p/3904995.html asp.net Razor 视图具有.cshtml后缀,可以轻松的实现c#代码和html标签的 ...

随机推荐

  1. 如何在多线程leader-follower模式下正确的使用boost::asio。

    #include <assert.h> #include <signal.h> #include <unistd.h> #include <iostream& ...

  2. [转]深入理解JavaScript的变量作用域

    1.JavaScript的作用域链 2.函数体内部,局部变量的优先级比同名的全局变量高. 3.JavaScript没有块级作用域. 4.函数中声明的变量在整个函数中都有定义. 5.未使用var关键字定 ...

  3. HTML的页面IE注释

    我们常常会在网页的HTML里面看到形如[if lte IE 9]……[endif]的代码,表示的是限定某些浏览器版本才能执行的语句,那么这些判断语句的规则是什么呢?请看下文: <!--[if ! ...

  4. Mac SVN 设置代理(Proxy)并 Checkout 代码

    1. 设置代理 Finder 菜单里面 -> 前往 -> 前往文件夹 -> /Users/username/.subversion -> 编辑文件 servers 在文件的 [ ...

  5. Java设计模式之建造者模式(Builder)

    前言: 最近一直在学习okHttp,也对其做了一些整理,okHttp和Retrofit结合大大加速我们的开发效率,源码里面采用了很多设计模式,今天我们来学习一下其中的设计模式之一建造者模式. 建造者模 ...

  6. xUnit安装及注意事项

    前言 对于单元测试,想必大家都已再熟悉不过了,同时单元测试的重要性也越发突出,在招聘中也特别强调单元测试,但是对于微软内置的单元测试还是太过于繁琐,于是都在寻找一种简洁并且更加轻量的测试工具.用的最多 ...

  7. UWP开发之Mvvmlight实践三:简单MVVM实例开发(图文详解付代码)

    在做MVVM各种框架对比之前,我觉得有必要先自己做一个简单的MVVM实现案例比较好,这样就可以看到自己实现的时候有那些不方便的地方.而各种框架又是怎么解决我们这些麻烦的. 案例介绍:用户登录画面,没有 ...

  8. 安装nginx

    [yum安装nginx] yum clean all(这步不执行会出现no more mirrors to try错误) cd /etc/yum.repos.d/ vi nginx.repo 填写 [ ...

  9. 你所不知道的15个Axure使用技巧

    你有用原型开发工具吗?如果有,那你用的是Axure还是别的? 从以前就喜欢使用Axure,主要是觉得它能清楚的表达设计的思路,还有交互的真实再现,能让看的人一目了然,昨天看了这篇博文,便更加确定Axu ...

  10. swift2.0 如何隐藏和设置状态栏

    1.在ViewController中操作当前ViewController的状态栏/** 隐藏状态栏 */ override func prefersStatusBarHidden() -> Bo ...