1. 程式人生 > >【aspnetcore】使用TagHelper制作分頁組件

【aspnetcore】使用TagHelper制作分頁組件

可用 ase aml control 簡單的 rem sys int start 分享圖片

自定義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傳入的視圖的數據,調用時請按實際情況替換即可。

結束,謝謝~

【aspnetcore】使用TagHelper制作分頁組件