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。
html 复制代码
<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

csharp 复制代码
    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,内容如下:

html 复制代码
@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 复制代码
@Html.Partial("SearchIndex", Model.ViewMyObject)

主页面控制器

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

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

  1. 通过ViewBag传递的变量,在初始化主页面的对象时也要初始化;
  2. 如果要带搜索功能的话,一定要先完成搜索/筛选,最后写分页。如果提前写了分页,那搜索功能会只局限在当前页面;
  3. 初始化ViewMyObject时,对于IPagedList<>类型的变量,不能直接使用来自类似这样的语句的变量var myObject = from m in db.myObject select m;,而要经过一个OrderBy操作,不然会报错:
shell 复制代码
The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.

只要取消蓝圈部分的注释就不会报错了。

更新表格数据的代码如下:

csharp 复制代码
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
html 复制代码
@using (Html.BeginForm("SearchIndex", "Home", FormMethod.Get))
{}

@Html.PagedListPager(Model.MyObject, page => Url.Action("SearchIndex", new { 查询参数 }))

后端

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

相关推荐
源代码•宸33 分钟前
Leetcode—3. 无重复字符的最长子串【中等】
经验分享·后端·算法·leetcode·面试·golang·string
0和1的舞者1 小时前
基于Spring的论坛系统-前置知识
java·后端·spring·系统·开发·知识
invicinble2 小时前
对于springboot
java·spring boot·后端
码界奇点3 小时前
基于Spring Boot与Vue的校园后台管理系统设计与实现
vue.js·spring boot·后端·毕业设计·源代码管理
爱编程的小庄3 小时前
Rust 发行版本及工具介绍
开发语言·后端·rust
Apifox.4 小时前
测试用例越堆越多?用 Apifox 测试套件让自动化回归更易维护
运维·前端·后端·测试工具·单元测试·自动化·测试用例
sunnyday04264 小时前
Nginx与Spring Cloud Gateway QPS统计全攻略
java·spring boot·后端·nginx
康王有点困4 小时前
Link入门
后端·flink
海南java第二人4 小时前
Spring Boot全局异常处理终极指南:打造优雅的API错误响应体系
java·spring boot·后端
小楼v5 小时前
消息队列的核心概念与应用(RabbitMQ快速入门)
java·后端·消息队列·rabbitmq·死信队列·交换机·安装步骤