首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET MVC 使用 MvcPager 實作分頁與 AJAX 無縫分頁完整教學

     編輯:ASP.NET 基礎

套件介紹

MvcPager (Webdiyer) 是 ASP.NET MVC 經典分頁套件,支援同步分頁、AJAX 非同步分頁、自訂樣式模板,NuGet 安裝:Install-Package MvcPager。

資料模型與 ViewModel

public class Article
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public DateTime CreateTime { get; set; }
}

public class ArticleListViewModel
{
    public PagedList<Article> Articles { get; set; }
    public string Keyword { get; set; }
}

控制器實作:同步與 AJAX 双模式

public class ArticleController : Controller
{
    private readonly IArticleRepository _repo;

    public ArticleController(IArticleRepository repo) => _repo = repo;

    // 同步分頁
    public async Task<ActionResult> Index(int page = 1, string keyword = "")
    {
        int pageSize = 10;
        var (items, total) = await _repo.SearchAsync(keyword, page, pageSize);
        
        var pagedList = new PagedList<Article>(items, page, pageSize) { TotalItemCount = total };
        
        return View(new ArticleListViewModel { Articles = pagedList, Keyword = keyword });
    }

    // AJAX 部分視圖回傳
    public async Task<ActionResult> _ArticleList(int page = 1, string keyword = "")
    {
        int pageSize = 10;
        var (items, total) = await _repo.SearchAsync(keyword, page, pageSize);
        var pagedList = new PagedList<Article>(items, page, pageSize) { TotalItemCount = total };
        
        return PartialView("_ArticleList", new ArticleListViewModel { Articles = pagedList, Keyword = keyword });
    }
}

視圖實作

1. 主視圖 Index.cshtml (含搜尋表單與 AJAX 分頁區塊)

@model ArticleListViewModel
@using Webdiyer.WebControls.Mvc

<div class="container">
    @* 搜尋表單 *@
    @using (Html.BeginForm("Index", "Article", FormMethod.Get, new { id = "searchForm" }))
    {
        <div class="input-group mb-3">
            @Html.TextBox("keyword", Model.Keyword, new { @class = "form-control", placeholder = "輸入關鍵字..." })
            <span class="input-group-btn">
                <button type="submit" class="btn btn-primary">搜尋</button>
            </span>
        </div>
    }

    @* 文章列表容器 (AJAX 更新目標) *@
    <div id="articleList">
        @{ Html.RenderPartial("_ArticleList", Model); }
    </div>

    @* AJAX 分頁導航 *@
    @Ajax.Pager(Model.Articles, new PagerOptions
    {
        PageIndexParameterName = "page",
        HttpMethod = HttpMethod.Get,
        AjaxOptions = new AjaxOptions
        {
            UpdateTargetId = "articleList",      // 更新容器 ID
            LoadingElementId = "loadingSpinner", // 可選:載入中動畫
            OnSuccess = "onPageLoaded"           // 可選:完成回呼
        },
        // 樣式自訂 (Bootstrap 4/5)
        ContainerTagName = "nav",
        CssClass = "pagination justify-content-center",
        CurrentPagerItemTemplate = "<li class=\"page-item active\"><a class=\"page-link\" href=\"#\">{0}</a></li>",
        DisabledPagerItemTemplate = "<li class=\"page-item disabled\"><span class=\"page-link\">{0}</span></li>",
        PagerItemTemplate = "<li class=\"page-item\"><a class=\"page-link\" href=\"{1}\">{0}</a></li>",
        PrevPageText = "« 上一頁",
        NextPageText = "下一頁 »",
        FirstPageText = "首頁",
        LastPageText = "末頁",
        NumericPagerItemCount = 5
    })
    <div id="loadingSpinner" class="text-center d-none"><span class="spinner-border"></span></div>
</div>

@section Scripts {
    <script>
        function onPageLoaded() {
            // 換頁後捲動至列表頂部
            $('html, body').animate({ scrollTop: $('#articleList').offset().top - 100 }, 300);
        }
    </script>
}

2. 部分視圖 _ArticleList.cshtml

@model ArticleListViewModel

<table class="table table-striped table-hover">
    <thead>
        <tr><th>ID</th><th>標題</th><th>建立時間</th></tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Articles)
        {
            <tr>
                <td>@item.Id</td>
                <td>@Html.DisplayFor(m => item.Title)</td>
                <td>@item.CreateTime.ToString("yyyy/MM/dd HH:mm")</td>
            </tr>
        }
    </tbody>
</table>

@* 同步分頁備援 (JS 失效時仍可運作) *@
@if (Request.IsAjaxRequest() == false)
{
    @Html.Pager(Model.Articles, new PagerOptions
    {
        PageIndexParameterName = "page",
        ContainerTagName = "nav",
        CssClass = "pagination justify-content-center",
        // ... 樣式設定同上
    })
}

進階技巧

  • 保持搜尋條件:Pager 會自動保留 QueryString 中的 `keyword` 參數,無需額外處理。
  • 自訂路由:若路由非預設,可在 `PagerOptions` 設定 `RouteValues` 字典傳遞額外參數。
  • 效能優化:資料層務必使用 `Skip/Take` 配合 `OrderBy`,避免撈全表再分頁。
  • 樣式客製:透過 `*PagerItemTemplate` 屬性完全掌控 HTML 結構,支援 Tailwind、Bulma 等任意 CSS 框架。

常見問題

Q: AJAX 分頁換頁後 URL 不變?
A: 這是預期行為 (局部更新)。若需 URL 同步,可在 `OnSuccess` 回呼中使用 `history.pushState` 更新瀏覽器網址列。

Q: 如何整合到 ASP.NET Core?
A: MvcPager 原版僅支援 MVC 5。Core 專案建議改用 X.PagedList.Mvc.Core 或自行實作 TagHelper (參考本系列其他文章)。

善用 MvcPager 靈活的模板系統,能快速產出符合設計規範、體驗流暢的分頁介面,是 MVC 專案的利器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved