第66章 基于.Net(Core)x框架的开源分页插件

news/2024/5/6 12:45:55/文章来源:https://blog.csdn.net/zhoujian_911/article/details/126669346

1 Jquery DataTable 分页插件

    Jquery DataTable分页插件是完全基于javaScript的,所以它是跨框架的,即不管你使用的是那种语言,那种平台开发网站程序,基本上都能通过使用Jquery DataTable分页插件实现分页操作。

    在nopCommerce开发者通过后台代码对Jquery DataTable分页插件的分页操作前后台实现都进行了重构定义,因此nopCommerce程序中Jquery DataTable分页插件的实现与nopCommerce程序的耦合十分紧密,所的它的独立性极差,从而造成了它只能用于学习,而不能在其它程序中以及其快速和低廉的代价进行移值和复用。

    下面我将大家介绍两个能够快速和低廉的代价进行移值和复用的并基于.Net(Core)x框架的开源分页插件,即这个两分页插件只能用于基于.Net(Core)x框架开发的Web程序,如果大家有更好的选择请在评论区留言。

2 MvcCorePager 分页插件

   我最早接触的开源分页插件就是杨涛的AspNetPager分页控件(当前版本:7.5.1),该分页控件是基于.Net Framework框架的,同时由于该控件的最后版本的更构日期为:2015-6-9,所以该插件已经适合集成到在当前的程序中实现分页操作,但不可否认的是AspNetPager分页控件是我当前所知的使用最为傻瓜,移值和复用最为快速和低廉的分页插件。所以作为对Jquery DataTable分页插件的替代,我最早查看的就是杨涛的MvcCorePager分页控件,但是它与的AspNetPager分页控件相比差距巨大,虽然它的最后提交日期为:22-5-27,但是当前的版本依然为:0.1.0,且通过Nuget引用的是该版本且日期为:2019/5/17,因此我不知Nuget引用是最后的提交版本,还是最早提交的版本,同时的MvcCorePager分页插件实现与自定义的JavaScript代码紧密耦合,由于上述原因到目前为止它不是1个好的选择。作为分页操作的另一种实现,其源代码还是具有一定的学习价值的。

    MvcCorePager分页控件源代码,如果使用最新版本的VisualStudio打开并运行,会有许多的异常产生,从而造成该程序不能正常被执行,本人对该源代码进行了以下重构定义,从而保证该程序能够正常执行。

    1、通过Nuget把Newtonsoft.Json、Microsoft.Extensions.FileProviders.Embedded引用更新到最新的版本。

    2、在Startup.Demo.ConfigureServices方法中定义语句:

                //由于.Net(Core)3框架及其以后的版本不在支持使用app.UserMvc()内置管道中件间定义路由映射模型;

            //如果需要.Net(Core)3框架及其以后的版本能够使用app.UserMvc()内置管道中件间定义路由映射模型,则必须配置定义下面1行的语句,否则就会出现异常:

            //“System.InvalidOperationException:Endpoint Routing does not support 'IApplicationBuilder.UseMvc(...)'. To use 'IApplicationBuilder.UseMvc' set 'MvcOptions.EnableEndpointRouting = false' inside 'ConfigureServices(...).

            services.AddMvc(options => { options.EnableEndpointRouting = false; });

3Src.csproj重构:

原Src.csproj定义

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">

        <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />

        <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />

        <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.8" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net5.0' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup>

      <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />

</ItemGroup>

当前程序执行到Webdiyer.AspNetCore.PostConfigure方法中的var filesProvider = new ManifestEmbeddedFileProvider(GetType().Assembly, "wwwroot");语句时,会产生异常:“System.InvalidOperationException:Could not load the embedded file manifest 'Microsoft.Extensions.FileProviders.Embedded.Manifest.xml' for assembly 'Webdiyer.AspNetCore.MvcCorePager'.

<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">

        <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />

        <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net5.0' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup Condition=" '$(TargetFramework)' == 'net6.0' ">

        <FrameworkReference Include="Microsoft.AspNetCore.App" />

    </ItemGroup>

    <ItemGroup>

      <PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="6.0.0" />

      <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.8" />
</ItemGroup>

注意:必须执行“生成”按钮对“Src.csproj”执行“生成”操作直到“依赖项”中的所有“!”消失,否则在程序执行进依然会出现上述异常信息。

4、MvcCorePager插件内嵌是Ajax分页功能结合自定义的JavaScript,该JavaScript绝对是一个小众的产品,所以我对MvcCorePager插件的健壮性有着严重的担忧。

5、由于.Net(Core)x框架对比于.NetFramework框架来说极度的不稳定,和快速的被迭代,MvcCorePager插件为了适应这种变化通过对Src.csproj不断的重构,以对不同版本.Net(Core)x框架进行支持,但是我以为更好的解决方案是构建不同的版本,这样使用Nugut可以明确的引用这些第3方分页插件,下面要讲解到的PagedList.Mvc.Core分页插件就是这样做的。

对以上功能更为具体实现和注释见:MvcCorePager-master(22-08-27重构版)

3 X.PagedList.Mvc.Core分页插件

    X.PagedList.Mvc.Core分页插件中Ajax分页功能是结合jquery.unobtrusive-ajax.js中的方法实现的,jquery.unobtrusive-ajax.js,被大量的开发者高频率的使用,所以我对X.PagedList.Mvc.Core分页插件的健壮性就没有了担忧,同时由于通过版本的重构,Nuget可以根据.Net(Core)x框架明确的引用不同版本的X.PagedList.Mvc.Core分页插件,所以它是我目前能够找到的最好用于.Net(Core)x框架Web程序的分页控件。

    但是X.PagedList.Mvc.Core分页插件中Ajax分页功能基于jquery.unobtrusive-ajax.js,所以其Ajax局部刷新实现也必须基于其助记HMTL标签属性:

AjaxOptions(Ajax.BeginForm)

HTML attribute(助记HMTL标签属性)

Confirm

data-ajax-confirm

HttpMethod

data-ajax-method

InsertionMode

data-ajax-mode

LoadingElementDuration

data-ajax-loading-duration

LoadingElementId

data-ajax-loading

OnBegin

data-ajax-begin

OnComplete

data-ajax-complete

OnFailure

data-ajax-failure

OnSuccess

data-ajax-success

UpdateTargetId

data-ajax-update

Url

 data-ajax-url

    这种实现方式虽然入门容易,但是实现比较复杂的Ajax局部刷新,在与Jquery DataTables插件来说功能上就有些力有不殆了,需要开发者自定义JavaScript/Jquery来实现这些功能,这些与我们这些对JavaScript/Jquery做到基本能用的开发者而言,有悖我们的初衷,所以开发者的选择,要根据自己的实际情况,我的建议是在Jquery DataTables插件上多下功功夫。

1 X_PagedListModel

/// <summary>

    /// 【X_PagedList分页列表--类】

    /// <remarks>

    /// 摘要:

    ///     该类及其属性成员实例,为X.PagedList.Mvc.Core插件渲染显示提供基本且必须的数据支撑。

    /// </remarks>

    public class X_PagedListModel

    {

        #region 拷贝构造方法

        /// <summary>

        /// 【拷贝构造方法】

        /// <remarks>

        /// 摘要:

        ///     通过拷贝构造方法为该类中的属性成员赋值实例化初始值。

        /// </remarks>

        /// </summary

        public X_PagedListModel()

        {

            //设置Jquery DataTable插件每页最多的行数(默认值):10,PageSize>=1。 

            PageSize = 10;

            PageNumber = 1;

        }

        #endregion

        #region 属性--X.PagedList.Mvc.Core插件

        /// <summary>

        /// 【页面大小】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定的X.PagedList.Mvc.Core插件每页最多的行数值:(默认值)10,PageSize>=1。 

        /// </remarks>

        /// </summary>

        public int PageSize { get; set; }

        /// <summary>

        /// 【索引】

        /// <remarks>

        /// 摘要:

        ///     获取/设置1个指定的X.PagedList.Mvc.Core插件指定页面相对应的索引值:(默认值)1,PageNumber>=1。 

        /// </remarks>

        /// </summary>

        public int PageNumber { get; set; }

        /// <summary>

        /// 【学生分页列表】

        /// <remarks>

        /// 摘要:

        ///     获取/设置把所有的学生实例,存储到X.PagedList.Mvc.Core插件的分页列表实例中。 

        /// </remarks>

        /// </summary>

        public IPagedList<Student> StudentIPagedList { get; set; }

        #endregion

        #region 属性--学生实体

        /// <summary>

        /// 【姓名】

        /// <remarks>

        /// 摘要:

        ///     获取/设置查询模型类1个指定实例的学生姓名。

        /// </remarks>

        /// </summary>

        [Display(Name = "姓名")]

        public string? StudnetName { get; set; }//支持空字符串查询操作,效果=“重置”。

        #endregion

    }

2 X_PagedListController

public class X_PagedListController : Controller

    {

        private readonly EFCoreContext _context;

        public X_PagedListController(EFCoreContext context)

        {

            _context = context;

        }

        public IActionResult Index(int? pageSize, int? pageNumber,  string studentName, X_PagedListModel x_PagedListModel)

        {

            // 设置分页列表模型实例。

            x_PagedListModel.PageSize = (pageSize == null || pageSize <= 0) ? x_PagedListModel.PageSize : Convert.ToInt32(pageSize);

            x_PagedListModel.PageNumber = (pageNumber == null || pageNumber <= 0) ? x_PagedListModel.PageNumber : Convert.ToInt32(pageNumber);

            x_PagedListModel.StudnetName = string.IsNullOrEmpty(studentName) ? x_PagedListModel.StudnetName : studentName;

            var customerData = (from studentsQuery in _context.Student select studentsQuery);

            //根据指定查询字符串,对所有实例进行查询操作。

            if (!string.IsNullOrEmpty(x_PagedListModel.StudnetName))

            {

                customerData = customerData.Where(m => m.StudnetName.Contains(x_PagedListModel.StudnetName));

            }

            customerData = customerData.OrderByDescending(s => s.Id);

            if (customerData.Count() % x_PagedListModel.PageSize == 0 && x_PagedListModel.PageNumber != 1)

                x_PagedListModel.PageNumber = x_PagedListModel.PageNumber - 1;

            if (customerData.Count() <= x_PagedListModel.PageSize || x_PagedListModel.PageNumber <= 1)

                x_PagedListModel.PageNumber = 1;

            x_PagedListModel.StudentIPagedList = customerData.ToPagedList(x_PagedListModel.PageNumber, x_PagedListModel.PageSize);

            return View(x_PagedListModel);

        }

        public IActionResult RenderPartial(int? pageSize, int? pageNumber, string studentName, X_PagedListModel x_PagedListModel)

        {

            // 设置分页列表模型实例。

            x_PagedListModel.PageSize = (pageSize == null || pageSize <= 0) ? x_PagedListModel.PageSize : Convert.ToInt32(pageSize);

            x_PagedListModel.PageNumber = (pageNumber == null || pageNumber <= 0) ? x_PagedListModel.PageNumber : Convert.ToInt32(pageNumber);

            x_PagedListModel.StudnetName = string.IsNullOrEmpty(studentName) ? x_PagedListModel.StudnetName : studentName;

            var customerData = (from studentsQuery in _context.Student select studentsQuery);

            //根据指定查询字符串,对所有实例进行查询操作。

            if (!string.IsNullOrEmpty(x_PagedListModel.StudnetName))

            {

                customerData = customerData.Where(m => m.StudnetName.Contains(x_PagedListModel.StudnetName));

            }

            customerData = customerData.OrderByDescending(s => s.Id);

            if (customerData.Count() % x_PagedListModel.PageSize == 0 && x_PagedListModel.PageNumber != 1)

                x_PagedListModel.PageNumber = x_PagedListModel.PageNumber - 1;

            if (customerData.Count() <= x_PagedListModel.PageSize || x_PagedListModel.PageNumber <= 1)

                x_PagedListModel.PageNumber = 1;

            x_PagedListModel.StudentIPagedList = customerData.ToPagedList(x_PagedListModel.PageNumber, x_PagedListModel.PageSize);

            return PartialView("_StudentList", x_PagedListModel);

        }

        public IActionResult AddPopup()

        {

            return View();

        }

        [HttpPost]

        public IActionResult AddPopup(Student model)

        {

            _context.Student.Add(model);//添加单个学生信息到数据库的指定表中

            _context.SaveChanges();

            ViewBag.RefreshPage = true;

            return View();

        }

        public IActionResult EditPopup(int studentId)

        {

            Student _model = _context.Student.SingleOrDefault(s => s.Id == studentId);

            return View(_model);

        }

        [HttpPost]

        public IActionResult EditPopup(Student model, int studentId)

        {

            if (model.Id == 0 && studentId != 0)

                model.Id = studentId;

            _context.Student.Update(model);//对数据库指定表1指定行中的学生信息进行更新操作

            _context.SaveChanges();

            ViewBag.RefreshPage = true;

            return View();

        }

        [HttpPost]

        public IActionResult DeleteJqueryDataTable(int pageNumber, int pageSize, int studentId, string studentName)

        {

            try

            {

                int result = 0;

                Student _model = _context.Student.SingleOrDefault(s => s.Id == studentId);

                //1、单独删除方法

                _context.Student.Remove(_model);//删除单个学生信息。

                //_context.Remove(_model);//直接在context上Remove()方法传入model,它会通过指定实体的实例,判断泛型实体的类型(Student)。

                result = _context.SaveChanges();

                X_PagedListModel _x_PagedListModel = new X_PagedListModel();

                _x_PagedListModel.StudnetName = studentName;

                return RenderPartial(pageSize, pageNumber, studentName, _x_PagedListModel);

            }

            catch (Exception)

            {

                throw;

            }

        }

        [HttpPost]

        public IActionResult DeleteIdArray(int pageNumber, int pageSize, string studentName, string studentIdArray)

        {

            try

            {

                if (!string.IsNullOrEmpty(studentIdArray))

                {

                    List<string> _idListString = studentIdArray.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();

                    List<int> _idArrayInt = _idListString.Where(pt => int.TryParse(pt, out var _)).Select(int.Parse).ToList();

                    List<Student> _studentList = new List<Student>();

                    foreach (var id in _idArrayInt)

                    {

                        Student _model = _context.Student.SingleOrDefault(s => s.Id == id);

                        _studentList.Add(_model);

                    }

                    foreach (var item in _studentList)

                    {

                        //1、单独删除方法

                        _context.Student.Remove(item);//删除单个学生信息。

                                                      //_context.Remove(_model);//直接在context上Remove()方法传入model,它会通过指定实体的实例,判断泛型实体的类型(Student)。

                        _context.SaveChanges();

                    }

                    int result = 0;

                    result = studentIdArray.Length;

                }

                X_PagedListModel _x_PagedListModel = new X_PagedListModel();

                _x_PagedListModel.StudnetName = studentName;

                return RenderPartial(pageSize, pageNumber, studentName, _x_PagedListModel);

            }

            catch (Exception)

            {

                throw;

            }

        }

    }

3 Index.cshtml

@model JsonTable.Models.X_PagedListModel

@{

    ViewData["Title"] = "学生信息";

}

@section styles

{

    <link rel="stylesheet" type="text/css" href="~/css/PagedList.css" />

}

<div id="nameListContainer" class="col-md-12">

    @await Html.PartialAsync("_StudentList", Model)

    @*

    注意:最好不要使用“@Html.Partial”,否则会出现“MVC1000”警告,原因是:使用 IHtmlHelper.Partial 或 IHtmlHelper.RenderPartial 扩展方法呈现分部将导致阻止调用。 由于线程池不足,因此这可能会导致性能降低和应用程序死锁问题(https://docs.microsoft.com/zh-cn/aspnet/core/diagnostics/mvc1000?view=aspnetcore-6.0)。

    @Html.Partial("_StudentList", Model)

    也可以直接使用“<partial/>”标签,从而避免上述的选择困难,“<partial/>”标签,是由HTML5新定义的,即HTML4及其以前的版本无该标签,只能使用  @await Html.PartialAsync/@Html.Partial实现局部渲染显示。

    <partial name="_StudentList" model="Model"/>

    *@

</div>

@section Scripts {

    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}

    <script type="text/javascript" src="~/lib/jquery-ajax-unobtrusive/dist/jquery.unobtrusive-ajax.js"></script>

    <script type="text/javascript">

        $(document).ready(function () {

            //复选框控件联动全选操作。

            CheckAllOpiton();

        });

        function CompletedLoaded() {

            //在查询操作完成后,把复选框控件联动全选操作,加载到X.PagedList.Mvc.Core插件中;否则在查询操作完成后,复选框控件联动全选操作将不起作用。

            CheckAllOpiton();

        };

        //复选框控件联动全选操作

        function CheckAllOpiton() {

            //全选

            $("#checkAll").click(function () {

                $("[name=checkItem]:checkbox").prop("checked", this.checked);

                var idArray = "";

                if (this.checked) {

                    $("[name=checkItem]:checkbox").each(function (index) {

                        idArray = idArray + $(this).val() + ",";

                    });

                }

                else {

                    idArray = "";

                }

                GetIdArray(idArray);

            });

            //复选框组的联动效果

            $("[name=checkItem]:checkbox").click(function () {

                var idArray = "";

                var flag = true;

                $("[name=checkItem]:checkbox").each(function (index) {

                    if (!this.checked) {

                        flag = false;

                    }

                    else {

                        idArray = idArray + $(this).val() + ",";

                    }

                });

                GetIdArray(idArray);

                $("#checkAll").prop("checked", flag);

            });

        }

        function GetIdArray(idArray) {

            idArray = idArray.slice(0, -1);

            var _url = "";

            _url = $("#deleteStudentList").attr('href');

            if (idArray != "") {

                if (_url.indexOf("&studentIdArray") > -1) {

                    var _length = _url.indexOf("&studentIdArray");

                    _url = _url.slice(0, _length);

                }

                _url = _url + "&studentIdArray=" + idArray;

            }

            else {

                if (_url.indexOf("&studentIdArray") > -1) {

                    var _length = _url.indexOf("&studentIdArray");

                    _url = _url.slice(0, _length);

                }

            }

            $("#deleteStudentList").attr('href', _url);

        };

    </script>

}

4 _StudentList.cshtml

@using JsonTable.Models

@using X.PagedList;

@using X.PagedList.Mvc.Core;

@using X.PagedList.Web.Common;

@model JsonTable.Models.X_PagedListModel

<div class="row">

    <div class="col-md-12">

        @* data-ajax="true" data-ajax-method="get" data-ajax-update="#nameListContainer" = .net framework: @using (Ajax.BeginForm("JqueryDataTableForm", "X_PagedList", new AjaxOptions() { HttpMethod = "get",UpdateTargetId = "nameListContainer" }, new { @class = "layui-form" }))}*@

        <form asp-action="RenderPartial" asp-route-pageSize="@Model.PageSize" asp-route-pageNumber="1" class="row gx-3 gy-2 align-items-center" id="JqueryDataTableForm" data-ajax="true" data-ajax-method="get" data-ajax-update="#nameListContainer" data-ajax-complete="CompletedLoaded">

            <div class="col-sm-3">

                <label asp-for="StudnetName" class="visually-hidden"></label>

                <input asp-for="StudnetName" class="form-control" />

                <span asp-validation-for="StudnetName" class="text-danger"></span>

            </div>

            <div class="col-sm-9">

                <button type="submit" id="searchStudent" class="btn btn-primary me-3">

                    <i class="fas fa-search"></i>

                    查询

                </button>

                <a asp-action="RenderPartial" asp-route-pageSize="@Model.PageSize" asp-route-pageNumber="1" type="button" class="btn btn-secondary me-3" data-ajax="true" data-ajax-method="get" data-ajax-update="#nameListContainer" data-ajax-complete="CompletedLoaded">

                    <i class="fa-solid fa-rotate-right"></i>

                    重置

                </a>

                <a asp-action="DeleteIdArray" asp-route-pageNumber="@Model.PageNumber" asp-route-pageSize="@Model.PageSize" asp-route-studentName="@Model.StudnetName"

                   type="button" id="deleteStudentList" class="btn btn-danger me-3" data-ajax="true" data-ajax-method="post" data-ajax-update="#nameListContainer" data-ajax-complete="CompletedLoaded">

                    <i class="far fa-trash-alt"></i>

                    批量删除

                </a>

                <a type="button" class="btn btn-success float-end" onclick="OpenWindow('@(Url.Action("AddPopup", "X_PagedList",

                        new {pageSize = @Model.PageSize,studentName = @Model.StudnetName, btnId = "btnRefreshProducts", formId = "JqueryDataTableForm" }))', 500, 500, true); return false;">

                    <i class="fas fa-plus"></i>

                    添加

                </a>

                @*“btnRefreshProducts”按钮标签必须定义在“Form”标签中或去掉对“window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();”的注释。*@

                <button type="button" id="btnRefreshProducts" class="d-none"></button>

            </div>

        </form>

    </div>

</div>

<table class="table table-bordered mt-3">

    <thead>

        <tr>

            <th style="width:5%">

                <input type="checkbox" id="checkAll" class="form-check-input checkBox25" title="checkAll">

            </th>

            <th style="width:5%">编号</th>

            <th style="width:15%">学号</th>

            <th style="width:10%">姓名</th>

            <th style="width:21%">专业</th>

            <th style="width:18%">年级</th>

            <th style="width:10%">班级</th>

            <th style="width:8%"></th>

            <th style="width:8%"></th>

        </tr>

    </thead>

    <tbody>

        @foreach (var item in Model.StudentIPagedList)

        {

            <tr>

                <th>

                    <input type="checkbox" name="checkItem" value="@item.Id" class="form-check-input checkBox25" title="checkItem">

                </th>

                <th>@item.Id</th>

                <th>@item.Code</th>

                <th>@item.StudnetName</th>

                <th>@item.Specialty</th>

                <th>@item.Grade</th>

                <th>@item.Category</th>

                <th>

                    <a type="button" class="btn btn-info" onclick="OpenWindow('@(Url.Action("EditPopup", "X_PagedList",

                        new {pageSize = @Model.PageSize, pageNumber = Model.PageNumber, studentName = @Model.StudnetName, studentId = @item.Id, btnId = "btnRefreshProducts", formId = "JqueryDataTableForm" }))', 500, 500, true); return false;">

                        编辑

                    </a>

                </th>

                <th>

                  @{

                        Dictionary<string, string> _queryString = new Dictionary<string, string>

                        {

                            { "pageNumber", Model.PageNumber.ToString() },

                            { "pageSize", Model.PageSize.ToString() },

                            { "studentId", item.Id.ToString() },

                            { "studentName", Model.StudnetName },

                        };

                   }

                    <a asp-action="DeleteJqueryDataTable" class='btn btn-danger' data-ajax="true" data-ajax-method="post" data-ajax-update="#nameListContainer" asp-all-route-data="_queryString" data-ajax-complete="CompletedLoaded">删除</a>

                </th>

            </tr>

        }

    </tbody>

</table>

<div class="text-end">

    @*注意:只能是Model(IPagedList<Student>);而不能是Model.StudentIPagedList,Model(JsonTable.Models.X_PagedListModel),否则X.PagedList.Mvc.Core分页插件中的页面索引按钮将不能被正常使用*@

    @Html.PagedListPager(Model.StudentIPagedList,

    page => Url.Action("RenderPartial", new X_PagedListModel{ PageNumber=page, PageSize = Model.PageSize, StudnetName = Model.StudnetName }),

    PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(

    new PagedListRenderOptions

    {

    LinkToFirstPageFormat = "1",//分页插件中"1"/"首页"的信息模版。

    LinkToLastPageFormat = Model.StudentIPagedList.PageCount.ToString(),//分页插件中Model.PageCount.ToString()/"尾页"的信息模版

    LinkToPreviousPageFormat = "上一页",//分页插件中"上一页"的信息模版。

    LinkToNextPageFormat = "下一页",//分页插件中"下一页"的信息模版。

    DisplayLinkToFirstPage = PagedListDisplayMode.IfNeeded,//分页插件中是否一直显示"1"/"首页"的枚举实例值,Always:一直显示;IfNeeded:如果当前页是第1页,则不显相应的按钮;如果不是则显示"1"/"首页",则显相应的按钮;Never:从不显示。

    DisplayLinkToLastPage = PagedListDisplayMode.IfNeeded,//分页插件中是否一直显显示Model.PageCount.ToString()/"尾页"的枚举实例值,Always:一直显示;IfNeeded:如果当前页是第后1页,则不显相应的按钮;如果不是则显示Model.PageCount.ToString()/"尾页";Never:从不显示。

    DisplayLinkToPreviousPage = PagedListDisplayMode.Never,//分页插件中是否一直显示"上一页"的枚举实例值,Always:一直显示;IfNeeded:如果当前页是第1页,则不显相应的按钮;如果不是显示"上一页",则显相应的按钮;Never:从不显示。

    DisplayLinkToNextPage = PagedListDisplayMode.Never,//分页插件中是否一直显示"下一页",的枚举实例值,Always:一直显示;IfNeeded:如果当前页是最后1页,则不显相应的按钮;如果不是显示"下一页",则显相应的按钮;Never:从不显示。

    //PageCountAndCurrentLocationFormat = "{0}/{1}",//分页插件显示,“{0}/{1}”的信息模版,{0}:当前页索引值;{1}:总页数值。,

    //DisplayPageCountAndCurrentLocation = true,//分页插件中是否显示,“{0}/{1}”信息,{0}:当前页索引值;{1}:总页数值。

    Display = PagedListDisplayMode.Always,//分页插件中是否一直在页面中进行显示的枚举实例值,Always:一直显示;IfNeeded:如果需要显示,如果不需要不显示;Never:从不显示。

    MaximumPageNumbersToDisplay = 5,//分页插件最多显示页面的索引值及其相应的按钮,当前显示“5”个页面的索引值及其相应的按钮,不算:"1"/"首页"、Model.PageCount.ToString()/"尾页"、"上一页"、 "下一页"的页面的索引值试及其相应的按钮。

    DisplayLinkToIndividualPages = true,//分页插件中是否为所有页面显示索引值及其相应的按钮。

    //DelimiterBetweenPageNumbers = "|",//每一页号之间会出现的文字。如果为空或空白是指定的,没有分隔符将显示。

    UlElementClasses = new[] { "pagination" },

    //ContainerDivClasses = new[] { "pagination-container" }

    ContainerDivClasses = new String[] { "pageList" }

    },

    new AjaxOptions()

    {

    HttpMethod = "POST",

    OnComplete = "CompletedLoaded",//在页面跳转操作完成后,把复选框控件联动全选操作,加载到X.PagedList.Mvc.Core插件中;否则在页面跳转操作完成后,复选框控件联动全选操作将不起作用。

    UpdateTargetId = "nameListContainer",

    }

    )

    )

    <div>

        每页 @Model.PageSize 条记录,本页有<strong class="text-danger">@Model.StudentIPagedList.Count</strong>条记录,共有 @Model.StudentIPagedList.TotalItemCount 条记录。第<strong class="text-danger">@(Model.StudentIPagedList.TotalItemCount <= Model.PageSize ? 1 : Model.PageNumber)</strong>页,共 @Model.StudentIPagedList.PageCount 页。

    </div>

</div>

5 AddPopup.cshtml

@model JsonTable.Domain.Students.Student

@{

    ViewData["Title"] = "添加学生信息";

}

@if (ViewBag.RefreshPage == true)

{

    <script type="text/javascript">

        window.opener.document.forms['@(Context.Request.Query["formId"])'].@(Context.Request.Query["btnId"]).click();

        //window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();

        //window.opener.document.getElementById("resetStudent").click();

        window.close();

        //编辑操作完成后,对父窗口的当前页进行整体刷新(浏览器需要被刷新)。

        var _url = "";

        _url = decodeURI('@(Url.Action("Index", "X_PagedList", new { pageSize = Context.Request.Query["pageSize"], studentName = Context.Request.Query["studentName"].ToString() }))', "UTF-8");

        _url = _url.replace(/&amp;/g, "&");

        window.opener.location.href = _url;

        window.location.href(window.opener.location.href);

    </script>

}

<div class="row">

    <div class="col-md-4">

        <form asp-action="AddPopup"

              asp-route-pageSize="@Context.Request.Query["pageSize"]"

              asp-route-studentName="@Context.Request.Query["studentName"]"

              asp-route-btnId="@Context.Request.Query["btnId"]"

              asp-route-formId="@Context.Request.Query["formId"]">

            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

       

            <div class="form-group">

                <label asp-for="Code" class="control-label"></label>

                <input asp-for="Code" class="form-control" />

                <span asp-validation-for="Code" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="StudnetName" class="control-label"></label>

                <input asp-for="StudnetName" class="form-control" />

                <span asp-validation-for="StudnetName" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Specialty" class="control-label"></label>

                <input asp-for="Specialty" class="form-control" />

                <span asp-validation-for="Specialty" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Grade" class="control-label"></label>

                <input asp-for="Grade" class="form-control" />

                <span asp-validation-for="Grade" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Category" class="control-label"></label>

                <input asp-for="Category" class="form-control" />

                <span asp-validation-for="Category" class="text-danger"></span>

            </div>

            <div class="form-group">

                <input type="submit" value="Create" class="btn btn-primary" />

            </div>

        </form>

    </div>

</div>

6 EditPopup.cshtml

@model JsonTable.Domain.Students.Student

@{

    ViewData["Title"] = "编辑学生信息";

}

@if (ViewBag.RefreshPage == true)

{

    <script type="text/javascript">

        window.opener.document.forms['@(Context.Request.Query["formId"])'].@(Context.Request.Query["btnId"]).click();

        //window.opener.document.getElementById("@Context.Request.Query["btnId"]").click();

        //window.opener.document.getElementById("resetStudent").click();

        window.close();

        //编辑操作完成后,对父窗口的当前页进行整体刷新(浏览器需要被刷新)。

        var _url = "";

        _url = decodeURI('@(Url.Action("Index", "X_PagedList", new { pageSize = Context.Request.Query["pageSize"], pageNumber = Context.Request.Query["pageNumber"], studentName = Context.Request.Query["studentName"].ToString() }))', "UTF-8");

        _url = _url.replace(/&amp;/g, "&");

        window.opener.location.href = _url;

        window.location.href(window.opener.location.href);

    </script>

}

<div class="row">

    <div class="col-md-12">

        <form asp-action="EditPopup"

              asp-route-pageSize="@Context.Request.Query["pageSize"]"

              asp-route-pageNumber="@Context.Request.Query["pageNumber"]"

              asp-route-studentName="@Context.Request.Query["studentName"]"

              asp-route-studentId="@Context.Request.Query["studentId"]"

              asp-route-btnId="@Context.Request.Query["btnId"]"

              asp-route-formId="@Context.Request.Query["formId"]">

            <div asp-validation-summary="ModelOnly" class="text-danger"></div>

            <div class="form-group">

                <label asp-for="Code" class="control-label"></label>

                <input asp-for="Code" class="form-control" />

                <span asp-validation-for="Code" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="StudnetName" class="control-label"></label>

                <input asp-for="StudnetName" class="form-control" />

                <span asp-validation-for="StudnetName" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Specialty" class="control-label"></label>

                <input asp-for="Specialty" class="form-control" />

                <span asp-validation-for="Specialty" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Grade" class="control-label"></label>

                <input asp-for="Grade" class="form-control" />

                <span asp-validation-for="Grade" class="text-danger"></span>

            </div>

            <div class="form-group">

                <label asp-for="Category" class="control-label"></label>

                <input asp-for="Category" class="form-control" />

                <span asp-validation-for="Category" class="text-danger"></span>

            </div>

            <div class="form-group">

                <input type="submit" value="Create" class="btn btn-primary" />

            </div>

        </form>

    </div>

</div>

    对以上功能更为具体实现和注释见:22-09-02-066_JsonTable(X.PagedList.Mvc.Core分页插件)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_4978.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TASK04分组|joyfulpandas

目录一、分组模式及其对象1. 分组的一般模式2. 分组依据的本质【练一练】【END】3.Groupby对象【练一练】【END】 size4. 分组的三大操作二、聚合函数1. 内置聚合函数【练一练】【END】2. agg方法【练一练】【练一练】【END】三、变换和过滤1. 变换函数与transform方法【练一练…

02|一条MySQL更新语句是如何执行的

02|一条MySQL更新语句是如何执行的 update T set cc1 where ID2;其实一条更新语句的执行操作和查询语句的执行操作基本相同->一条SQL查询语句是如何查询的&#xff1f;&#xff0c;唯一不同的是一条更新语句在执行过程中需要涉及到两个日志操作&#xff08;redo log、binlo…

四、集合

四、集合 集合和数组区别 &#xff08;1&#xff09;数组定长&#xff0c;集合不定长&#xff08;2&#xff09;数组可存基础数据类型和引用类型&#xff0c;集合只能存引用类型 位置&#xff1a;java.util.*; 这是一位仁兄的笔记&#xff0c;师出同门&#xff0c;点我跳转~ 1、…

高级js 面向对象 和面向过程 三种函数

判断数据类型 // 创建一个Cat对象&#xff0c;属性:颜色&#xff0c;品种&#xff0c;行为:吃&#xff0c;跑&#xff0c;捉老鼠var Cat new Object() //new一个对象Cat.catys red //属性Cat.catname cat //对象名// 行为Cat.catxw function () {console.log("喜欢跑&…

Python3,我用这种方式讲解python模块,80岁的奶奶都说能理解。建议收藏 ~ ~

Python模块讲解1、引言2、python模块详解2.1 含义2.2 代码示例2.3 进阶3、总结1、引言 小屌丝&#xff1a;鱼哥&#xff0c;你看天上的月亮越来越圆了。 小鱼&#xff1a;唉~ 又是一年团圆夜&#xff0c;又是一年中秋节。 小屌丝&#xff1a;嘿嘿&#xff0c;可不滴&#xff0…

二维凸包问题

什么是二维凸包 假设墙上顶一组钉子&#xff0c;这些钉子的集合为X&#xff0c;我们用橡皮筋围住这些钉子&#xff0c;橡皮筋的形状就是凸包(来源于网络)。 向量的叉乘 对于两个向量pq⃗\vec{pq}pq​和qr⃗\vec{qr}qr​ 如果pq⃗\vec{pq}pq​和qr⃗\vec{qr}qr​的叉积结果大于0…

分销商城小程序开发运营逻辑是什么?

商城分销现在用的人比较多&#xff0c;其中用的最多的差不多就是二级分销、三级分销&#xff0c;除了这两种分销方式&#xff0c;还有一种是一级分销&#xff0c;不过裂变效果可能不如二级分销、三级分销要好&#xff0c;所以用的人不是特别的多。 二级分销跟三级分销的逻辑都差…

C++PrimerPlus跟读记录【第五章】循环和关系表达式

1、for 循环 for(initialization; test-expression; updata-expression)test-expression 关系表达式&#xff0c;结果强制为bool类型&#xff0c;true or false。 表达式和语句 C表达式是 值 或 值与运算符的组合&#xff0c;每个表达式都有值。表达式只要加上分号&#xff0…

剑指offer32-42字符串数组的应用

剑指 Offer II 032. 有效的变位词 给定两个字符串 s 和 t &#xff0c;编写一个函数来判断它们是不是一组变位词&#xff08;字母异位词&#xff09;。t 是 s的变位词等价于「两个字符串不相等且两个字符串排序后相等」 注意&#xff1a;若 s 和 t 中每个字符出现的次数都相同…

QT QTextEdit富文本插入字体-表格-编号-图片-查找-语法高亮功能

QT QTextEdit富文本插入字体-表格-编号-图片与查找功能&#xff0c;输入char 自动变成蓝色-语法高亮功能 QTQTextEdit富文本插入字体-表格-编号-图片-查找-语法高亮功能.rar-QT文档类资源-CSDN下载QTQTextEdit富文本插入字体-表格-编号-图片-查找-语法高亮功能.rarhttps:/更多…

Vue使用脚手架(ref、props、mixin、插件、scoped)(七)

系列文章目录 第一章&#xff1a;Vue基础知识笔记&#xff08;模板语法、数据绑定、事件处理、计算属性&#xff09;&#xff08;一&#xff09; 第二章&#xff1a;Vue基础知识&#xff08;计算属性、监视属性、computed和watch之间的区别、绑定样式&#xff09;&#xff08;…

四、 java的对象和类

四、 java的对象和类 对象&#xff08;Object&#xff09;&#xff1a;对象是类的一个实例&#xff0c;有状态和行为。例如&#xff0c;一条狗是一个对象&#xff0c;它的状态有&#xff1a;颜色、名字、品种&#xff1b;行为有&#xff1a;摇尾巴、叫、吃等。类&#xff08;c…

物理服务器安装CentOS 7操作系统

目录 1、下载系统镜像 2、制作安装盘 2.1 方法一&#xff1a;光盘制作 2.2 方法二&#xff1a;U盘制作 3、更改bios启动顺序 4、安装CentOS 7操作系统 4.1 安装命令选择&#xff0c;及常见错误解决 4.2 语言选择 4.3 时区选择 4.4 软件选择 4.5 安装位置选择 4.6 手…

猿创征文|【C++游戏引擎Easy2D】学C++还不会绘制一个简单的二维图形?一篇文章教会你

&#x1f9db;‍♂️iecne个人主页&#xff1a;&#xff1a;iecne的学习日志 &#x1f4a1;每天关注iecne的作品&#xff0c;一起进步 &#x1f4aa;学C必看iecne 本文专栏&#xff1a;【C游戏引擎】. &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; ✨前…

Apache Maven 3.6.0的下载安装和环境配置(详细图解+不限速下载链接)

标题工具/原料 apache-maven-3.6.0 下载地址 云盘不限速下载 或者进入官网按下图下载 方法/步骤一 安装 打开压缩包&#xff0c;将maven压缩包解压至软件安装处&#xff0c;建议D根目录或其他&#xff0c;记住安装位置 类似于 方法/步骤二 环境变量配置 变量 1.新建变…

Eolink 通过可信云权威认证,数据保护能力业内领先!

Eolink 正式通过由中国信息通信研究院组织发起的可信云评估考核&#xff0c;在数据安全保障领域获得权威认证&#xff0c;并荣获 “企业级 SaaS 服务” 认证证书。 在云时代&#xff0c;保护用户数据安全、预防隐私泄露是数字化企服厂商的重中之重。Eolink 作为一个 API 在线管…

计算机毕业设计ssm+vue基本微信小程序的个人健康管理系统

项目介绍 首先,论文一开始便是清楚的论述了小程序的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了小程序的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数…

IIC协议详解

文章目录1 IIC简介2 IIC物理层2.1 IIC硬件2.2 IIC协议特点3 IIC协议层4数据传输4.1 IIC写数据4.2 IIC读数据1 IIC简介 IIC(Inter&#xff0d;Integrated Circuit)总线是一种由 NXP&#xff08;原 PHILIPS&#xff09;公司开发的两线式串行总线&#xff0c; 用于连接微控制器及其…

s19.基于 Kubernetes v1.25.0(kubeadm) 和 Docker 部署高可用集群(一)

基于 Kubernetes v1.25.0 和 Docker 部署高可用集群 主要内容 Kubernetes 集群架构组成容器运行时 CRIKubernetes v1.25 新特性Kubernetes v1.24 之后不再支持 Docker 的解决方案Kubernetes v1.25 高可用集群架构基于 Kubernetes v1.25.0 和 Docker 部署高可用集群实战案例 …

Redis持久化机制分析

什么是持久化&#xff1f; 简单来说持久化就是将数据保存到磁盘&#xff0c;让即使服务宕机、重启、断电等操作后数据仍热存在&#xff0c;并且是完整的。 1、为什么要持久化&#xff1f; 1、Redis是一个内存数据库&#xff0c;宕机之后存储在内存的数据会消失。2、Redis重启…