Razor Pages中为Partial View实现客户端分页求助
需求说明
我是Razor Pages初学者,当前功能是点击侧边栏Movies标签显示电影表格,搜索后通过Partial View更新数据。现在需要给初始展示的数据和Partial View添加客户端分页,总共有5000条数据,要求每页显示25条。尝试过Bootstrap Table但没成功,希望用jQuery和Ajax实现,以下是现有代码:
Movies.cshtml
@page @using Project.Models; @model Project.Pages.MovieModel @section scripts { <script src="/UnwatchedMovies.js"></script> } <div class="container"> <div class="col-12"> <h2> Movie Search </h2> </div> </div> <div> <form method="post" id="movies"> <div class="row"> <input type="text" id="searchInput"/> <button type="button" id="searchButton" onclick="searchMovies()"></button> </div> <div class="row"> <label class="switch"> <input type="checkbox" id="toggleMovies" onchange="searchMovies()"> <div class="slider"></div> </label> </div> </form> <div id="movieDataPartialView"> @await Html.PartialAsync("Movies/_MovieDataPartial",Model.Movies) </div> </div>
Movies.cshtml.cs
namespace Movies.Pages { public class MovieModel : PageModel { private readonly UnwatchedMovies _unwatchedMovies; public MovieModel(UnwatchedMovies unwatchedMovies) { _unwatchedMovies = unwatchedMovies; } public List<Movie> Movies {get; set;} public void OnGet() { Movies = _unwatchedMovies.GetMovies(null); } public PartialViewResult OnPostSearch([FromBody] Search search) { Movies = _unwatchedMovies.GetMovies(search); return new PartialViewResult { ViewName = "Movies/_MovieDataPartial", ViewData = new ViewDataDictionary<List<Movie>>(ViewData, Movies) }; } } }
_MovieDataPartial.cshtml(Partial View)
@model List<Project.Models.Movie> <div> <table id="tableData"> <thead> <tr> <th scope="col">Name</th> <th scope="col">Ratings</th> <th scope="col">Genre</th> </tr> </thead> <tbody id="bodyData"> @foreach(var movie in Model) { <td>@movie.Name</td> <td>@movie.Ratings</td> <td>@movie.Genre</td> } </tbody> </table> </div>
解决方案实现步骤
1. 修复Partial View结构并添加分页容器
先修正原Partial View中表格行的结构缺失问题,同时添加分页控件容器:
@model List<Project.Models.Movie> <div> <table id="tableData" class="table table-striped"> <thead> <tr> <th scope="col">Name</th> <th scope="col">Ratings</th> <th scope="col">Genre</th> </tr> </thead> <tbody id="bodyData"> @foreach(var movie in Model) { <tr> <td>@movie.Name</td> <td>@movie.Ratings</td> <td>@movie.Genre</td> </tr> } </tbody> </table> <!-- 分页控件容器 --> <div id="paginationControls" class="mt-3"></div> </div>
2. 编写客户端分页逻辑(UnwatchedMovies.js)
用jQuery实现全量数据存储、分页计算、页面渲染和搜索联动:
$(document).ready(function() { // 全局变量存储全量电影数据与分页参数 let allMovies = []; const pageSize = 25; let currentPage = 1; // 初始化:提取页面加载时的电影数据 allMovies = $("#bodyData tr").map(function() { return { name: $(this).find("td").eq(0).text(), ratings: $(this).find("td").eq(1).text(), genre: $(this).find("td").eq(2).text() }; }).get(); // 初始化分页控件与当前页数据 renderPagination(); renderCurrentPage(); // 搜索电影函数(替换原有逻辑) window.searchMovies = function() { const searchText = $("#searchInput").val().trim(); const toggleChecked = $("#toggleMovies").is(":checked"); $.ajax({ url: "/Movies?handler=Search", type: "POST", contentType: "application/json", data: JSON.stringify({ searchText: searchText, toggleState: toggleChecked // 匹配你的Search模型字段,按需调整 }), success: function(response) { // 解析返回的Partial View,提取全量电影数据 const tempTable = $(response).find("#bodyData"); allMovies = $(tempTable).find("tr").map(function() { return { name: $(this).find("td").eq(0).text(), ratings: $(this).find("td").eq(1).text(), genre: $(this).find("td").eq(2).text() }; }).get(); // 重置分页到第一页,重新渲染 currentPage = 1; renderPagination(); renderCurrentPage(); }, error: function(xhr) { console.error("搜索请求失败:", xhr.responseText); } }); }; // 渲染当前页数据 function renderCurrentPage() { const startIndex = (currentPage - 1) * pageSize; const endIndex = startIndex + pageSize; const currentMovies = allMovies.slice(startIndex, endIndex); $("#bodyData").empty(); currentMovies.forEach(movie => { const row = `<tr> <td>${movie.name}</td> <td>${movie.ratings}</td> <td>${movie.genre}</td> </tr>`; $("#bodyData").append(row); }); } // 生成分页控件 function renderPagination() { const totalPages = Math.ceil(allMovies.length / pageSize); const paginationContainer = $("#paginationControls"); paginationContainer.empty(); if (totalPages <= 1) return; // 上一页按钮 const prevButton = `<button class="btn btn-outline-primary me-1" ${currentPage === 1 ? 'disabled' : ''} onclick="changePage(${currentPage - 1})">上一页</button>`; paginationContainer.append(prevButton); // 动态显示页码(最多显示5个) let startPage = Math.max(1, currentPage - 2); let endPage = Math.min(totalPages, currentPage + 2); if (totalPages < 5) { startPage = 1; endPage = totalPages; } for (let i = startPage; i <= endPage; i++) { const pageButton = `<button class="btn btn-primary me-1 ${i === currentPage ? 'active' : ''}" onclick="changePage(${i})">${i}</button>`; paginationContainer.append(pageButton); } // 下一页按钮 const nextButton = `<button class="btn btn-outline-primary" ${currentPage === totalPages ? 'disabled' : ''} onclick="changePage(${currentPage + 1})">下一页</button>`; paginationContainer.append(nextButton); } // 切换页面函数 window.changePage = function(pageNum) { const totalPages = Math.ceil(allMovies.length / pageSize); if (pageNum < 1 || pageNum > totalPages) return; currentPage = pageNum; renderPagination(); renderCurrentPage(); }; });
3. 后端确认(确保返回全量数据)
保证UnwatchedMovies.GetMovies()方法返回所有符合条件的电影数据,不做服务端分页,因为我们要在客户端处理分页逻辑。
内容的提问来源于stack exchange,提问作者flash speedster
相关产品推荐
相关产品推荐

