zoukankan      html  css  js  c++  java
  • 【aspnetcore】使用TagHelper制作分页组件

    自定义TageHelper并不难,只要记住几个点:

    1. 继承TagHelper
    2. 定义需要在TagHelper中传入的参数,如果不需要参数,可忽略
    3. 重写Process方法
    4. 在Process中拼接要输出的HTML字符串
    5. 在Views > _ViewImports.cshtml 中添加引用

    仅此五步即可。

    接下来实现分页。这里要做的是一个像bootstrap一样的简单分页

    页面元素包括:首页链接 页码链接 尾页链接,也就是几个<a>标签,很简单,代码实现也就需要下面几步:

    1. 定义必要参数:记录总数 total,当前页码 pageIndex,每页显示的条数 pageSize,链接地址(不带分页参数)routeUrl
    2. 计算总页数 pageCount
    3. 拼接HTML字符串

    当然,一个可用的连接必然还要考虑到两个基本功能:

    1. 跳转时保留查询参数
    2. 如果页数很多,全部显示必然会破坏页面结构,所以只能显示当前页码周围固定数量的页码,而隐藏其他的页码。

    OK,下面是具体的代码实现:

    using Microsoft.AspNetCore.Razor.TagHelpers;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace Project.TagHelpers
    {
        public class MyPagerTagHelper : TagHelper
        {
            /// <summary>
            /// 数据总数
            /// </summary>
            public int Total { get; set; } = 0;
    
            /// <summary>
            /// 当前页码
            /// </summary>
            public int PageIndex { get; set; } = 1;
    
            /// <summary>
            /// 每页记录数
            /// </summary>
            public int PageSize { get; set; } = 20;
    
            /// <summary>
            /// 当前页路由
            /// </summary>
            public string RouteUrl { get; set; }
    
            /// <summary>
            /// 当前页的查询条件
            /// </summary>
            public string Query { get; set; }
    
            private string SetQueryString()
            {
                var result = new List<string>();
                if (!string.IsNullOrWhiteSpace(Query))
                {
                    if (Query.StartsWith("?"))
                    {
                        Query = Query.Remove(0, 1);
                    }
    
                    string[] paramList = Query.Split('&');
                    foreach (var param in paramList)
                    {
                        var paramName = param.Trim().ToLower();
                        if (!paramName.StartsWith("pageindex=") && !paramName.StartsWith("pagesize="))
                        {
                            result.Add(param);
                        }
                    }
                    // 用LINQ遍历
                    // result = paramList.Where(p => !p.ToLower().StartsWith("pageindex=") && !p.ToLower().StartsWith("pagesize=")).ToList();
                }
                result.Add("pageIndex={0}");
                result.Add("pageSize=" + PageSize.ToString());
                return "?" + string.Join('&', result);
            }
    
            public override void Process(TagHelperContext context, TagHelperOutput output)
            {
                output.TagName = "div";
                output.Attributes.Add("class", "my-pager");
    
                if (PageSize <= 0) { PageSize = 20; }
                if (PageIndex <= 0) { PageIndex = 1; }
                if (Total <= 0) { return; }
    
                //总页数
                var totalPage = Total / PageSize + (Total % PageSize > 0 ? 1 : 0);
                if (totalPage <= 0) { return; }
    
                Query = SetQueryString();
    
                //构造分页样式
                var sbPage = new StringBuilder(string.Empty);
                
                sbPage.Append("<ul class="pagination">");
                sbPage.AppendFormat("<li><a href="{0}{1}">首页</a></li>",
                    RouteUrl,
                    string.Format(Query, 1)
                );
    
                // 计算显示的页码
                int start = 1;
                int end = totalPage;
                bool hasStart = false;
                bool hasEnd = false;
    
                if (totalPage > 10)
                {
                    if (PageIndex > 5)
                    {
                        start = PageIndex - 4;
                        hasStart = true;
                    }
    
                    if (start + 9 < totalPage)
                    {
                        end = start + 9;
                        hasEnd = true;
                    }
                    else
                    {
                        end = totalPage;
                        start = totalPage - 9;
                    }
                }
    
                if (hasStart)
                {
                    sbPage.AppendFormat("<li><a href="{0}{1}">...</a></li>",
                        RouteUrl,
                        string.Format(Query, start - 1)
                    );
                }
    
                for (int i = start; i <= end; i++)
                {
                    sbPage.AppendFormat("<li {1}><a href="{2}{3}">{0}</a></li>",
                        i,
                        i == PageIndex ? "class="active"" : "",
                        RouteUrl,
                        string.Format(Query, i)
                    );
                }
    
                if (hasEnd)
                {
                    sbPage.AppendFormat("<li><a href="{0}{1}">...</a></li>",
                        RouteUrl,
                        string.Format(Query, end + 1)
                    );
                }
    
                sbPage.Append("<li>");
                sbPage.AppendFormat("<a href="{0}{1}">",
                                    RouteUrl,
                                    string.Format(Query, totalPage));
                sbPage.Append("尾页");
                sbPage.Append("</a>");
                sbPage.Append("</li>");
                sbPage.Append("</ul>");
    
                output.Content.SetHtmlContent(sbPage.ToString());
            }
        }
    }  

    话说,这不是一个令人满意的实现,特别是对查询字符串的处理上,不过此分页方案最终被放弃,也就没有继续深入,只提供思路,如有更好的实现方法,请留言告知,不胜感激。

    接下来,在Views > _ViewImports.cshtml 中插入代码

    @using Project.TagHelpers
    
    @addTagHelper *, Project.TagHelpers

    至此,自定义分页TageHelper完成,页面中调用方法如下:

    <my-pager total="@Model.RecordCount"
                page-index="@Model.PageIndex"
                page-size="@Model.PageSize"
                route-url="/Admin/WxAccount/Index"
                query="@Url.ActionContext.HttpContext.Request.QueryString">
    </my-pager>

    @Model.xxx是我通过Controller传入的视图的数据,调用时请按实际情况替换即可。

    结束,谢谢~

  • 相关阅读:
    执行shell脚本的四种方式(转)
    linux free命令详解(一)
    linux TOP命令各参数详解【转载】
    grep命令
    vim常用命令
    IntelliJ Idea注释模板--类注释、方法注释
    [Chrome]抓请求直接生成可执行代码
    记录Markdown工具Typora
    VSCODE 配置远程开发环境
    [Boost::Polygon]多边形相减得到新的多边形序列
  • 原文地址:https://www.cnblogs.com/diwu0510/p/9748774.html
Copyright © 2011-2022 走看看