ASP.NET MVC-制作可排序的表格组件-PagedList版
环境:
win10
参考:
学习ASP.NET MVC(十一)——分页 - DotNet菜园 - 博客园
https://www.cnblogs.com/chillsrc/p/6554697.html
ASP.NET MVC+EF框架实现分页_ef 异步分页-CSDN博客
https://blog.csdn.net/qq_40052237/article/details/106599528
本文略去CRUD代码,默认读者可以连接数据库实现增删改查。之前写过:
ASP.NETMVC-简单例子-数据库查询+razor使用+项目发布_mvc怎么数据库搜索-CSDN博客
https://blog.csdn.net/pxy7896/article/details/139837179
目录
- 效果
- 准备工作
- 思路
- 实现
- ViewModel
- 前端
- 主页面
- 主页面控制器
- 彩蛋
- 前端
- 后端
效果
准备工作
- 使用NuGet安装PagedList.Mvc,安装完成后PagedList也会被安装好。
- 可选:使用BeginForm时需要异步提交,所以使用jquery.unobtrusive-ajax.min.js。
可以下载放到Scripts文件夹下,使用BundleConfig引入。
思路
跟上一篇文章类似,区别是ViewModel里使用IPagedList,连带着前端和后端都有变化。下面直接放代码了。
上一篇:
ASP.NET MVC-制作获取数据并分页的组件-原生代码版-CSDN博客
https://blog.csdn.net/pxy7896/article/details/140372682
实现
ViewModel
public class ViewMyObject { public IPagedList MyObject { get; set; } public string Search { get; set; } // 关键词 public string Stype { get; set; } // sur-type public string SortBy { get; set; } // asc or desc public string PageSize { get; set; } // 每页多少个对象 public int TotalRows { get; set; } // 总共有多少条数据 }
前端
需要注意的有两点:
- Ajax.BeginForm可以发送异步请求,直接更新UpdateTargetId的内容,这个直接更新整个cshtml就可以了;
- BeginForm下,@Html.XX中形成的元素id与name一致,并且是可以跟指定的Action中的形参一致的:
- @Html.PagedListPager可以非常灵活地使用,通过设置AjaxOptions可以异步地更新数据。
给这个片段起名SearchIndex,内容如下:
@model xxx.ViewMyObject @using PagedList.Mvc @{ ViewBag.Title = "查询"; }
@using (Ajax.BeginForm("SearchIndex", "Home", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "resultDiv" })) {种类: @Html.DropDownList("Category", "All") 名称: @Html.TextBox("searchString") 排序: @Html.DropDownList("sortBy", "不排序") 每页显示 @Html.DropDownList("pageSize", "10") 条数据
} @if (Model != null) {共 @Model.TotalRows 条数据,第@(Model.MyObject.PageCount Url.Action("SearchIndex", new { category = Model.Stype, search = Model.Search, sortBy = Model.SortBy, page, pageSize = Model.PageSize }), PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing( new PagedListRenderOptions { Display = PagedListDisplayMode.IfNeeded, DisplayLinkToFirstPage = PagedListDisplayMode.Never, DisplayLinkToLastPage = PagedListDisplayMode.Never, DisplayLinkToIndividualPages = true, MaximumPageNumbersToDisplay = 5, DisplayLinkToPreviousPage = PagedListDisplayMode.Always, DisplayLinkToNextPage = PagedListDisplayMode.Always }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "resultDiv", InsertionMode = InsertionMode.Replace } ) )}主页面
与上一篇一致:
@Html.Partial("SearchIndex", Model.ViewMyObject)
主页面控制器
首先,必须要在主页面带的对象的类定义里增加ViewMyObject类的变量,并且在初始化主页面的对象时,也初始化这个ViewMyObject类的变量。
其次,数据更新的代码如下所示,需要注意的点有:
- 通过ViewBag传递的变量,在初始化主页面的对象时也要初始化;
- 如果要带搜索功能的话,一定要先完成搜索/筛选,最后写分页。如果提前写了分页,那搜索功能会只局限在当前页面;
- 初始化ViewMyObject时,对于IPagedList类型的变量,不能直接使用来自类似这样的语句的变量var myObject = from m in db.myObject select m;,而要经过一个OrderBy操作,不然会报错:
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
只要取消蓝圈部分的注释就不会报错了。
更新表格数据的代码如下:
public ActionResult SearchIndex(string Category, string searchString, string sortBy, int? page, string pageSize) { MyDbContext db = new MyDbContext(); // 构造类型选择框 var cateLst = new List(); var cateQry = from d in db.myObject orderby d.stype select d.stype; cateLst.AddRange(cateQry.Distinct()); ViewBag.Category = new SelectList(cateLst); //排序选项 var orderbyLst = new Dictionary { { "名称升序", "name_asc" }, { "名称降序", "name_desc" } }; ViewBag.sortBy = new SelectList(orderbyLst, "Value", "Key"); // 每页放多少数据的选项 ViewBag.pageSize = new SelectList(new List() { "20", "50", "100"}); // 获取原始数据 var myObject = from m in db.myObject select m; // searchString匹配name if (!String.IsNullOrEmpty(searchString)) { myObject = myObject.Where(b => b.name.Contains(searchString)); } // sort by name order switch (sortBy) { case "name_asc": myObject = myObject.OrderBy(b => b.name); break; case "name_desc": myObject = myObject.OrderByDescending(b => b.name); break; default: myObject = myObject.OrderBy(b => b.id); break; } // sort by type if (!string.IsNullOrEmpty(Category)) { //string tmpType = Category.Replace("'", "''"); myObject = myObject.Where(x => x.stype == Category); } //分页 int pageItems = 10;// 每页放几个 if (!string.IsNullOrEmpty(pageSize)) { pageItems = int.Parse(pageSize); } // view model ViewMyObject vbp = new ViewMyObject(); int currentPage = (page ?? 1); IPagedList pageMyObject = myObject.ToPagedList(currentPage, pageItems); vbp.MyObject = pageMyObject; vbp.Stype = Category; vbp.SortBy = sortBy; vbp.Search = searchString; vbp.PageSize = pageSize; vbp.TotalRows = myObject.Count(); return PartialView("SearchIndex", vbp); }
彩蛋
如果要在单独的网页上更新,不需要做成组件,就比较简单了。此时不需要考虑异步,搜索按钮的提交和页面选择都可以直接制作url。
前端
需要修改两处:
- 使用Html.BeginForm
- 翻页部分直接用Url.Action
@using (Html.BeginForm("SearchIndex", "Home", FormMethod.Get)) {} @Html.PagedListPager(Model.MyObject, page => Url.Action("SearchIndex", new { 查询参数 }))
后端
修改SearchIndex(),将return PartialView("SearchIndex", 对象);改为return View(对象)即可。