如何实现视图内PagedList分页表格无整页刷新更新数据
实现方案
1. 先修复视图嵌套叠加问题
你当前出现视图嵌套的核心原因是分页Action返回了带完整布局的View,每次请求都会把整页内容加载到局部区域,直接替换成返回**无布局的局部视图(Partial View)**即可解决:
- 把每个表格+对应分页控件的代码单独拆成独立的局部视图,局部视图不要设置
Layout = xxx,仅保留当前表格的渲染逻辑。 - 分页Action返回结果时用
PartialView()替代View(),只会返回表格相关的HTML片段,不会加载外层布局。
2. 实现多表格独立无刷新分页
要做到点击页码只刷新目标表格、不重载整页,按以下步骤改造:
- 主视图中给三个表格分别添加独立的容器,设置唯一ID,每个容器内渲染对应表格的局部视图:
<!-- 产品表容器 --> <div id="productTableWrap"> @Html.Partial("_ProductTablePartial", Model.Products) </div> <!-- 订单表容器 --> <div id="orderTableWrap"> @Html.Partial("_OrderTablePartial", Model.Orders) </div> <!-- 用户表容器 --> <div id="userTableWrap"> @Html.Partial("_UserTablePartial", Model.Users) </div>
- 修改局部视图中的分页控件配置,新增
tableType参数区分当前分页属于哪个表格,以产品表局部视图_ProductTablePartial.cshtml为例:
@using PagedList; @using PagedList.Mvc; @model IPagedList<Product> <table class="table"> <thead> <tr><th>产品名称</th><th>价格</th><th>库存</th></tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td>@item.Name</td> <td>@item.Price</td> <td>@item.Stock</td> </tr> } </tbody> </table> <!-- 分页控件,传入表格类型标识 --> @Html.PagedListPager(Model, page => Url.Action("GetTablePagedData", new { page, tableType = "product" }), new PagedListRenderOptions { EnableUnobtrusiveAjaxReplacing = false })
另外两个表格的局部视图同理,分页链接里的tableType分别传order、user即可。
- 改造后端分页Action,统一处理三个表格的分页逻辑,支持按请求类型返回不同格式结果:
public ActionResult GetTablePagedData(int? page, string tableType) { const int pageSize = 10; int currentPage = page ?? 1; switch (tableType) { case "product": var productPageData = database.GetProducts().ToPagedList(currentPage, pageSize); // 返回HTML片段 if (Request.Headers["X-Return-Format"] == "html") { return PartialView("_ProductTablePartial", productPageData); } // 返回JSON/字符串格式 return Json(new { list = productPageData.Select(p => new { p.Id, p.Name, p.Price, p.Stock }), pageInfo = new { currentPage = productPageData.PageNumber, totalPage = productPageData.PageCount, totalCount = productPageData.TotalItemCount } }, JsonRequestBehavior.AllowGet); case "order": var orderPageData = database.GetOrders().ToPagedList(currentPage, pageSize); if (Request.Headers["X-Return-Format"] == "html") { return PartialView("_OrderTablePartial", orderPageData); } return Json(new { list = orderPageData.Select(o => new { o.Id, o.OrderNo, o.Amount, o.CreateTime }), pageInfo = new { currentPage = orderPageData.PageNumber, totalPage = orderPageData.PageCount, totalCount = orderPageData.TotalItemCount } }, JsonRequestBehavior.AllowGet); case "user": var userPageData = database.GetUsers().ToPagedList(currentPage, pageSize); if (Request.Headers["X-Return-Format"] == "html") { return PartialView("_UserTablePartial", userPageData); } return Json(new { list = userPageData.Select(u => new { u.Id, u.UserName, u.Phone }), pageInfo = new { currentPage = userPageData.PageNumber, totalPage = userPageData.PageCount, totalCount = userPageData.TotalItemCount } }, JsonRequestBehavior.AllowGet); default: return new HttpStatusCodeResult(400, "无效的表格类型"); } }
- 添加前端JS逻辑,拦截分页链接的默认跳转行为,发送AJAX请求只替换对应表格容器的内容:
$(function () { // 全局拦截分页按钮点击 $(document).on('click', '.pagination a', function (e) { e.preventDefault(); var requestUrl = $(this).attr('href'); if (!requestUrl) return; // 解析链接中的表格类型,定位要替换的容器 var urlParam = new URLSearchParams(requestUrl.split('?')[1]); var targetType = urlParam.get('tableType'); var $targetContainer; switch (targetType) { case 'product': $targetContainer = $('#productTableWrap'); break; case 'order': $targetContainer = $('#orderTableWrap'); break; case 'user': $targetContainer = $('#userTableWrap'); break; default: return; } // 发送AJAX请求加载对应分页数据 $.ajax({ url: requestUrl, type: 'GET', headers: { 'X-Return-Format': 'html' }, beforeSend: function () { $targetContainer.addClass('loading'); }, success: function (res) { $targetContainer.html(res); }, error: function () { alert('分页数据加载失败,请重试'); }, complete: function () { $targetContainer.removeClass('loading'); } }) }) })
3. 返回string/Json类型的说明
不需要修改PagedList的核心使用逻辑,只需要在Action中根据请求标识判断返回类型即可:
- 需要返回string类型时,直接用
return Content("自定义字符串内容")返回即可,你可以把分页数据拼接成需要的字符串格式再返回。 - 需要返回Json类型时,直接从
ToPagedList()生成的分页对象中提取当前页数据、总页数、当前页码、总条数等信息,序列化成匿名对象后用return Json()返回即可,完全不影响分页功能的正常使用。
注意:如果需要保留分页后浏览器前进后退的能力,可以在AJAX加载完成后调用
history.pushState把当前分页参数写入URL,按需扩展即可。
内容的提问来源于stack exchange,提问作者green cross
相关产品推荐
相关产品推荐

