【发布】弹性分页类PagingBuild Class 附带测试
园子里分页代码是老生常谈了,可惜找到的不是有问题就是满足不了自己的需求,静下心来重新改写了在用的一个分页器,因为有测试会比较稳定,虽然测试覆盖可能还不是很全面。
用例代码:
new CNBlogs.Presentation.Web.PagingBuilder() { FirstPageLink = firstLink, OnlickJsFunc = "Return true;", PageIndex = (int)(p??1), ShowPageCount = 11, TotalCount = 1, UrlFormat = urlFormate, PageSize = PAGE_SIZE, AjaxUrl = "/" }; //MVC View Code @{ Html.RenderPaging(Model.Paging); }
先上代码:
public class PagingBuilder { private TextWriter _writer; private int _totalCount; private int _pageIndex; private int _pageSize; private int _showPageCount; private string _urlFormat; private string _onclickJsFunc; private string _firstPageLink; private string _ajaxUrl = "/ToolkitPaging/load"; private int _totalPageCount; private int _lastPage = 1; #region Properties public bool OnlyLinkText { get; set; } /// <summary> /// 总记录数 /// </summary> public int TotalCount { get { return _totalCount; } set { _totalCount = value; } } /// <summary> /// 当前页码 /// </summary> public int PageIndex { get { return _pageIndex; } set { _pageIndex = value; } } /// <summary> /// 每页显示的记录数 /// </summary> public int PageSize { get { return _pageSize; } set { _pageSize = value; } } /// <summary> /// 默认显示的页码数 /// </summary> public int ShowPageCount { get { return _showPageCount; } set { _showPageCount = value; } } /// <summary> /// 页码链接地址 /// </summary> public string UrlFormat { get { return _urlFormat; } set { _urlFormat = value; } } /// <summary> /// 页码链接onclick事件处理js方法,pageIndex,pageSize参数无需添加 /// </summary> public string OnlickJsFunc { get { return _onclickJsFunc; } set { _onclickJsFunc = value; } } /// <summary> /// 第1页链接地址 /// </summary> public string FirstPageLink { get { return _firstPageLink; } set { _firstPageLink = value; } } /// <summary> /// ajax加载分页的请求地址,默认是/paging/load /// </summary> public string AjaxUrl { get { return _ajaxUrl; } set { _ajaxUrl = value; } } /// <summary> /// ajax加载分页的js回调方法,有默认实现 /// </summary> private string _ajaxCallbak; public string AjaxCallbak { get { return _ajaxCallbak; } set { _ajaxCallbak = value; } } /// <summary> /// 顶部分页Html标签Id /// </summary> private string _topPagerId = "pager_top"; public string TopPagerId { get { return _topPagerId; } set { _topPagerId = value; } } public bool IsRenderScript { get; set; } #endregion public PagingBuilder() { IsRenderScript = true; } public void Render(TextWriter writer) { _writer = writer; Render(); } public void Render() { if (_totalCount <= _pageSize) { return; } if (this.IsRenderScript) { _writer.Write("<div id=\"paging_block\">"); } if (!this.OnlyLinkText) { _writer.Write("<div class=\"pager\">"); } //总页数 _totalPageCount = (_totalCount + _pageSize - 1) / _pageSize; int currint = _showPageCount / 2; if (_pageIndex - currint <= 1) { Head(); } else if (_pageIndex + currint >= _totalPageCount) { Tail(); } else { Middle(); } if (!this.OnlyLinkText) { _writer.Write("</div>"); } if (IsRenderScript) { _writer.Write("</div>"); RenderScript(); } } private void Head() { int totalPageCount = _totalPageCount; int currint = _showPageCount / 2; if (_pageIndex > 1) { //处理上一页的连接 RenderPage(_pageIndex - 1, this.OnlyLinkText ? "Prev " : "< Prev"); } for (int i = 1; i <= (_showPageCount > totalPageCount ? totalPageCount : _showPageCount); i++) { RenderPage(i); } if (_lastPage + 1 < totalPageCount) { _writer.Write("..."); } if (_lastPage < totalPageCount) { RenderPage(totalPageCount); } if (_pageIndex < totalPageCount) { //处理下一页的链接 RenderPage(_pageIndex + 1, this.OnlyLinkText ? "Next" : "Next >"); } } private void Middle() { int totalPageCount = _totalPageCount; int currint = _showPageCount / 2; if (_pageIndex > 1) { //处理上一页的连接 RenderPage(_pageIndex - 1, this.OnlyLinkText ? "Prev " : "< Prev"); } if (_pageIndex - currint > 1) { //处理首页连接 RenderPage(1); if(_pageIndex-currint>2) {_writer.Write("...");} } for (int i = 0; i <= _showPageCount; i++) { var c = _pageIndex + i - currint; //一共最多显示10个页码,前面5个,后面5个 if (c > 1 && c < totalPageCount) { if (c != 2 && _lastPage == 1) { _writer.Write("..."); } RenderPage(c); } } if (_pageIndex + currint < totalPageCount) { if (_lastPage + 1 != totalPageCount) { _writer.Write("..."); } RenderPage(totalPageCount); } if (_pageIndex < totalPageCount) { //处理下一页的链接 RenderPage(_pageIndex + 1, this.OnlyLinkText ? "Next" : "Next >"); } } private void Tail() { int totalPageCount = _totalPageCount; int currint = _showPageCount / 2; if (_pageIndex > 1) { //处理上一页的连接 RenderPage(_pageIndex - 1, this.OnlyLinkText ? "Prev " : "< Prev"); } if (_pageIndex - currint > 1&&_totalPageCount>_showPageCount) { //处理首页连接 RenderPage(1); } for (int i = ((_totalPageCount - _showPageCount) < 0 ? 0 : (_totalPageCount - _showPageCount)) + 1; i <= _totalPageCount; i++) { if (i > 2 && _lastPage == 1) { _writer.Write("..."); } RenderPage(i); } if (_pageIndex < totalPageCount) { //处理下一页的链接 RenderPage(_pageIndex + 1, this.OnlyLinkText ? "Next" : "Next >"); } } private void RenderPage(int pageIndex) { RenderPage(pageIndex, string.Empty); } private void RenderPage(int pageIndex, string pageText, bool visible = true) { _lastPage = pageIndex; if (OnlyLinkText) { if (pageIndex == _pageIndex) { _writer.Write("-"); } _writer.Write(" "); if (!string.IsNullOrEmpty(pageText)) { _writer.Write(pageText); } else { _writer.Write(pageIndex); } if (pageIndex == _pageIndex) { _writer.Write("-"); } return; } string link = ""; if (string.IsNullOrEmpty(_urlFormat)) { link = "javascript:void(0)"; } else { if (pageIndex == 1 && !string.IsNullOrEmpty(_firstPageLink)) { link = _firstPageLink; } else { link = string.Format(_urlFormat, pageIndex); } } _writer.Write("<a href=\""); _writer.Write(link); _writer.Write("\""); //style if (!visible) { _writer.Write(" style=\"display:none\""); } #region class if (string.IsNullOrEmpty(pageText)) { _writer.Write(" class=\"p_"); _writer.Write(pageIndex); if (pageIndex == _pageIndex) { _writer.Write(" current"); } _writer.Write("\""); } #endregion #region onclick if (!string.IsNullOrEmpty(_onclickJsFunc)) { _writer.Write(" onclick=\""); if (_onclickJsFunc.IndexOf("()") < 0) { _writer.Write(_onclickJsFunc.Replace(")", "," + pageIndex + "," + _pageSize + ")")); } else { _writer.Write(_onclickJsFunc.Replace("()", "(" + pageIndex + "," + _pageSize + ")")); } _writer.Write(";buildPaging(" + pageIndex + ");return false;"); _writer.Write("\""); } #endregion #region id //if (pageText.IndexOf("<") > -1) //{ // _writer.Write(" id=\"paging_p_prev\""); //} //else if (pageText.IndexOf(">") > -1) //{ // _writer.Write(" id=\"paging_p_next\""); //} #endregion _writer.Write(">"); if (string.IsNullOrEmpty(pageText)) { _writer.Write(pageIndex); } else { _writer.Write(pageText); } _writer.Write("</a>"); } private void RenderScript() { _writer.Write("<script type=\"text/javascript\">"); _writer.Write("function buildPaging(pageIndex){var pagingBuider="); _writer.Write(JsonConvert.SerializeObject(this)); _writer.Write(";"); _writer.Write("pagingBuider.pageIndex=pageIndex;"); _writer.Write("$.ajax({url:pagingBuider.AjaxUrl,data:JSON.stringify(pagingBuider),"); _writer.Write("type:'post',dataType:'text',contentType:'application/json; charset=utf-8',"); _writer.Write("success:function (data) { $('#paging_block').html(data); "); _writer.Write("var pagerTop=$('#"); _writer.Write(_topPagerId); _writer.Write("');"); _writer.Write("if(pageIndex>1){$(pagerTop).html(data).show();}else{$(pagerTop).hide();}}});"); _writer.WriteLine("}</script>"); } }
测试分页效果,这里设定的弹性显示页数为11:
Render_Test : Passed
1//1
Result:
1//2
Result:- 1- 2 Next
2//2
Result: Prev 1- 2-
1//3
Result:- 1- 2 3 Next
2//3
Result: Prev 1- 2- 3 Next
3//3
Result: Prev 1 2- 3-
1//9
Result:- 1- 2 3 4 5 6 7 8 9 Next
3//9
Result: Prev 1 2- 3- 4 5 6 7 8 9 Next
5//9
Result: Prev 1 2 3 4- 5- 6 7 8 9 Next
7//9
Result: Prev 1 2 3 4 5 6- 7- 8 9 Next
9//9
Result: Prev 1 2 3 4 5 6 7 8- 9-
1//11
Result:- 1- 2 3 4 5 6 7 8 9 10 11 Next
3//11
Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11 Next
5//11
Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11 Next
7//11
Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 Next
10//11
Result: Prev 1 2 3 4 5 6 7 8 9- 10- 11 Next
1//13
Result:- 1- 2 3 4 5 6 7 8 9 10 11... 13 Next
3//13
Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11... 13 Next
5//13
Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11... 13 Next
7//13
Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 12 13 Next
8//13
Result: Prev 1... 3 4 5 6 7- 8- 9 10 11 12 13 Next
9//13
Result: Prev 1... 3 4 5 6 7 8- 9- 10 11 12 13 Next
10//13
Result: Prev 1... 3 4 5 6 7 8 9- 10- 11 12 13 Next
11//13
Result: Prev 1... 3 4 5 6 7 8 9 10- 11- 12 13 Next
12//13
Result: Prev 1... 3 4 5 6 7 8 9 10 11- 12- 13 Next
1//200
Result:- 1- 2 3 4 5 6 7 8 9 10 11... 200 Next
3//200
Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11... 200 Next
5//200
Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11... 200 Next
7//200
Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 12 13... 200 Next
8//200
Result: Prev 1...... 3 4 5 6 7- 8- 9 10 11 12 13 14... 200 Next
9//200
Result: Prev 1...... 4 5 6 7 8- 9- 10 11 12 13 14 15... 200 Next
10//200
Result: Prev 1...... 5 6 7 8 9- 10- 11 12 13 14 15 16... 200 Next
11//200
Result: Prev 1...... 6 7 8 9 10- 11- 12 13 14 15 16 17... 200 Next
12//200
Result: Prev 1...... 7 8 9 10 11- 12- 13 14 15 16 17 18... 200 Next
88//200
Result: Prev 1...... 83 84 85 86 87- 88- 89 90 91 92 93 94... 200 Next
199//200
Result: Prev 1... 190 191 192 193 194 195 196 197 198- 199- 200 Next
Result:
1//2
Result:- 1- 2 Next
2//2
Result: Prev 1- 2-
1//3
Result:- 1- 2 3 Next
2//3
Result: Prev 1- 2- 3 Next
3//3
Result: Prev 1 2- 3-
1//9
Result:- 1- 2 3 4 5 6 7 8 9 Next
3//9
Result: Prev 1 2- 3- 4 5 6 7 8 9 Next
5//9
Result: Prev 1 2 3 4- 5- 6 7 8 9 Next
7//9
Result: Prev 1 2 3 4 5 6- 7- 8 9 Next
9//9
Result: Prev 1 2 3 4 5 6 7 8- 9-
1//11
Result:- 1- 2 3 4 5 6 7 8 9 10 11 Next
3//11
Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11 Next
5//11
Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11 Next
7//11
Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 Next
10//11
Result: Prev 1 2 3 4 5 6 7 8 9- 10- 11 Next
1//13
Result:- 1- 2 3 4 5 6 7 8 9 10 11... 13 Next
3//13
Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11... 13 Next
5//13
Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11... 13 Next
7//13
Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 12 13 Next
8//13
Result: Prev 1... 3 4 5 6 7- 8- 9 10 11 12 13 Next
9//13
Result: Prev 1... 3 4 5 6 7 8- 9- 10 11 12 13 Next
10//13
Result: Prev 1... 3 4 5 6 7 8 9- 10- 11 12 13 Next
11//13
Result: Prev 1... 3 4 5 6 7 8 9 10- 11- 12 13 Next
12//13
Result: Prev 1... 3 4 5 6 7 8 9 10 11- 12- 13 Next
1//200
Result:- 1- 2 3 4 5 6 7 8 9 10 11... 200 Next
3//200
Result: Prev 1 2- 3- 4 5 6 7 8 9 10 11... 200 Next
5//200
Result: Prev 1 2 3 4- 5- 6 7 8 9 10 11... 200 Next
7//200
Result: Prev 1 2 3 4 5 6- 7- 8 9 10 11 12 13... 200 Next
8//200
Result: Prev 1...... 3 4 5 6 7- 8- 9 10 11 12 13 14... 200 Next
9//200
Result: Prev 1...... 4 5 6 7 8- 9- 10 11 12 13 14 15... 200 Next
10//200
Result: Prev 1...... 5 6 7 8 9- 10- 11 12 13 14 15 16... 200 Next
11//200
Result: Prev 1...... 6 7 8 9 10- 11- 12 13 14 15 16 17... 200 Next
12//200
Result: Prev 1...... 7 8 9 10 11- 12- 13 14 15 16 17 18... 200 Next
88//200
Result: Prev 1...... 83 84 85 86 87- 88- 89 90 91 92 93 94... 200 Next
199//200
Result: Prev 1... 190 191 192 193 194 195 196 197 198- 199- 200 Next