【发布】弹性分页类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
原文地址:https://www.cnblogs.com/jinzhao/p/2587838.html