WebGrid分页功能失效求助:绑定数据后分页无法正常工作
嘿,我看你这WebGrid分页的问题,主要是AJAX配置不匹配、后台没处理分页参数,还有表单提交和WebGrid默认行为冲突导致的。我给你一步步拆解修复:
1. 先搞定AJAX更新容器的ID匹配问题
你初始化WebGrid时指定了ajaxUpdateContainerId: "grid",但实际生成的网格HTML属性ID是"gridlogs"——这就导致WebGrid找不到要更新的容器,AJAX分页直接罢工。把两者统一:
@{ var gridview = new WebGrid( source: Model.LstLog, rowsPerPage: 20, ajaxUpdateContainerId: "gridlogs", canSort: false ); }
2. 让后台Action支持分页参数
WebGrid分页时会自动把当前页码page传给后台,但你的HttpPost方法完全没接收这个参数,分页时自然拿不到对应页的数据。修改后台方法,加上分页参数并调整数据获取逻辑:
[HttpPost] public ActionResult EmpLog(int? page, string selectedValue) { var model = new YourModelType(); // 记得实例化你的模型类 model.Values = GetDDLInfo(); model.SelectedValue = selectedValue; // 回传选中的下拉值到视图 // 先拿到完整的筛选后数据 var allLogs = GetLogInfo(selectedValue); // 处理分页逻辑:默认第一页,每页20条 int pageNumber = page ?? 1; int pageSize = 20; model.LstLog = allLogs.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList(); // 给模型加个TotalCount属性,存总记录数——WebGrid需要这个来生成分页控件 model.TotalCount = allLogs.Count(); return View(model); }
记得给你的模型新增TotalCount和SelectedValue属性,前者用来让WebGrid计算总页数,后者用来保留下拉框的筛选状态。
3. 修正视图里的空数据判断
你视图里写的是@if (Model.Lst != null),但实际绑定的是Model.LstLog,这里明显写错了,改成:
@if (Model.LstLog != null && Model.LstLog.Any()) { // 渲染WebGrid的代码 }
4. 给WebGrid传入总记录数
初始化WebGrid时加上totalRowCount参数,传入模型的总记录数,这样分页控件才能正确显示总页数:
@{ var gridview = new WebGrid( source: Model.LstLog, rowsPerPage: 20, ajaxUpdateContainerId: "gridlogs", canSort: false, totalRowCount: Model.TotalCount ); }
5. 避免表单提交干扰AJAX分页
你把WebGrid放在了Html.BeginForm里面,WebGrid的AJAX分页请求会被表单的Post行为干扰。最简单的办法是把WebGrid移到表单外面,然后加个隐藏域存下拉框的选中值,确保分页时不会丢失筛选条件:
@using (Html.BeginForm("EmpLog", "Labels", FormMethod.Post)) { @Html.DropDownListFor(x => x.SelectedValue, Model.Values, "----Select----", new { id = "ddlName", @class = "form-control col-md-6" }) <input type="submit" value="Search" id="btnSearch" class="btn btn-default" /> } <!-- WebGrid移到表单外 --> @{ var gridview = new WebGrid( source: Model.LstLog, rowsPerPage: 20, ajaxUpdateContainerId: "gridlogs", canSort: false, totalRowCount: Model.TotalCount, ajaxUpdateCallback: "updatePagerParams" ); } @if (Model.LstLog != null && Model.LstLog.Any()) { @gridview.GetHtml( htmlAttributes: new { id = "gridlogs" }, fillEmptyRows: false, alternatingRowStyle: "alternate-row", headerStyle: "grid-header", footerStyle: "grid-footer", selectedRowStyle: "grid-selected-row", rowStyle: "grid-row-style", mode: WebGridPagerModes.All, firstText: "<< First", previousText: "< Prev", nextText: "Next >", lastText: "Last >>", columns: new[] { gridview.Column("View", header: null, style: "click_able", format: @<text><a href="javascript:ViewFullDetails('@item.Id');">View</a></text>, canSort: false), gridview.Column("JoinDate",header: "Join Date"), gridview.Column("DeptName",header: "Dept Name"), gridview.Column("Project",header: "Project") } ) } <!-- 隐藏域存选中的下拉值 --> <input type="hidden" id="hiddenSelectedValue" value="@Model.SelectedValue" /> <script> function updatePagerParams() { // 给所有分页链接加上选中的下拉值参数 var selectedVal = document.getElementById('hiddenSelectedValue').value; var pagerLinks = document.querySelectorAll('#gridlogs .webgrid-pager a'); pagerLinks.forEach(link => { let href = link.href; // 移除已有的selectedValue参数,避免重复 href = href.replace(/([?&])selectedValue=[^&]*(&|$)/, '$1').replace(/&$/, ''); // 添加新参数 href += href.includes('?') ? `&selectedValue=${selectedVal}` : `?selectedValue=${selectedVal}`; link.href = href; }); } </script>
另外,建议把后台的HttpPost改成HttpGet——WebGrid的AJAX分页默认是Get请求,这样更贴合它的原生行为,也避免了表单Post的一些麻烦。
按这些步骤调整后,你的WebGrid分页应该就能正常工作了,而且分页时还能保留下拉框的筛选状态~
内容的提问来源于stack exchange,提问作者Rocky

