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; });
3、Src.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(/&/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(/&/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分页插件)。