• 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

    效果

    在这里插入图片描述
    在这里插入图片描述

    准备工作

    1. 使用NuGet安装PagedList.Mvc,安装完成后PagedList也会被安装好。
      在这里插入图片描述
    2. 可选:使用BeginForm时需要异步提交,所以使用jquery.unobtrusive-ajax.min.js。
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-ajax-unobtrusive/3.2.6/jquery.unobtrusive-ajax.min.js">script>
    

    可以下载放到Scripts文件夹下,使用BundleConfig引入。

    思路

    跟上一篇文章类似,区别是ViewModel里使用IPagedList<>,连带着前端和后端都有变化。下面直接放代码了。

    上一篇:
    ASP.NET MVC-制作获取数据并分页的组件-原生代码版-CSDN博客
    https://blog.csdn.net/pxy7896/article/details/140372682

    实现

    ViewModel

        public class ViewMyObject
        {
            public IPagedList<MyObject> 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; } // 总共有多少条数据
        }
    

    前端

    需要注意的有两点:

    1. Ajax.BeginForm可以发送异步请求,直接更新UpdateTargetId的内容,这个直接更新整个cshtml就可以了;
    2. BeginForm下,@Html.XX中形成的元素id与name一致,并且是可以跟指定的Action中的形参一致的:
      在这里插入图片描述
    3. @Html.PagedListPager可以非常灵活地使用,通过设置AjaxOptions可以异步地更新数据。

    给这个片段起名SearchIndex,内容如下:

    @model xxx.ViewMyObject
    @using PagedList.Mvc
    
    @{
        ViewBag.Title = "查询";
    }
    
    <div id="resultDiv">
        @using (Ajax.BeginForm("SearchIndex", "Home", new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "resultDiv" }))
        {
            <p>
                种类: @Html.DropDownList("Category", "All")
                名称: @Html.TextBox("searchString")
                排序: @Html.DropDownList("sortBy", "不排序")
                每页显示
                @Html.DropDownList("pageSize", "10")
                条数据
                <input type="submit" value="查询" />
            p>
        }
    
    
    
        @if (Model != null)
        {
            <table>
                
            table>
    		
            <div>
                共 @Model.TotalRows 条数据,第@(Model.MyObject.PageCount < Model.MyObject.PageNumber ? 0 : Model.MyObject.PageNumber)页,共 @Model.MyObject.PageCount 页
    
                @Html.PagedListPager(Model.MyObject,
                    page => 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
                        }
                    )
                )
    
            div>
        }
    
    div>
    

    主页面

    与上一篇一致:

    @Html.Partial("SearchIndex", Model.ViewMyObject)
    

    主页面控制器

    首先,必须要在主页面带的对象的类定义里增加ViewMyObject类的变量,并且在初始化主页面的对象时,也初始化这个ViewMyObject类的变量。

    其次,数据更新的代码如下所示,需要注意的点有:

    1. 通过ViewBag传递的变量,在初始化主页面的对象时也要初始化;
    2. 如果要带搜索功能的话,一定要先完成搜索/筛选,最后写分页。如果提前写了分页,那搜索功能会只局限在当前页面;
    3. 初始化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<string>();
        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<string, string>
        {
            { "名称升序", "name_asc" },
            { "名称降序", "name_desc" }
        };
        ViewBag.sortBy = new SelectList(orderbyLst, "Value", "Key");
    	
    	// 每页放多少数据的选项
        ViewBag.pageSize = new SelectList(new List<string>() { "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<MyObject> 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。

    前端

    需要修改两处:

    1. 使用Html.BeginForm
    2. 翻页部分直接用Url.Action
    @using (Html.BeginForm("SearchIndex", "Home", FormMethod.Get))
    {}
    
    @Html.PagedListPager(Model.MyObject, page => Url.Action("SearchIndex", new { 查询参数 }))
    

    后端

    修改SearchIndex(),将return PartialView("SearchIndex", 对象);改为return View(对象)即可。

  • 相关阅读:
    【Vue】组件通信与方法暴露实践
    猿创征文|网络原理——UDP/TCP协议
    吃鸡游戏出现msvcp140.dll缺失的四个解决方法
    【圆满落幕】IDCF社区&天津理工大学华信软件学院校友会技术沙龙丨IDCF
    2024春季春日主题活动策划方案
    [LeetCode]剑指 Offer 12. 矩阵中的路径
    lv7 嵌入式开发-网络编程开发 03 TCP/IP与五层体系结构
    【Linux】UNIX 术语中,换页与交换的区别和Linux 术语中,换页与交换的区别?
    中国密码算法与NIST标准对比
    Windows上启用NTP服务器功能
  • 原文地址:https://blog.csdn.net/pxy7896/article/details/140378049