MVC + Bootstrap + Drapper use PagedList. Mvc supports multi-query condition paging and mvcpagedlist Paging
A few days ago, I made a small project and used MVC + Bootstrap. Previously, paging was used to asynchronously load partial Mvc views, because this is a small project, just a little. Generally, the list page has query conditions. The following describes how to use Drapper + PagedList. Mvc to support paging of multiple query conditions.
In MVC, we generally use a strong Model to build this Model by analyzing the Orders display page.
1. query the Parameter Model
Public class OrderQueryParamModel {// <summary> // Order No. /// </summary> public string OrderNo {get; set ;} /// <summary> /// customer name // </summary> public string CustomerName {get; set ;}}
2. Orders paging Data Model
PagedList provides a StaticPagedList <T> generic class to encapsulate data. (Check the source code of StaticPagedList. It is very convenient to use. initialize the data subset, pageNumber, pageSize, and totalCount of the T type.
)
public StaticPagedList(IEnumerable<T> subset, IPagedList metaData) : this(subset, metaData.PageNumber, metaData.PageSize, metaData.TotalItemCount) { }
3. Orders displays the overall Model of the page
public class OrderViewModel { public OrderQueryParamModel QueryModel { get; set; } public PagedList.StaticPagedList<OrderModel> OrderList { get; set; } }
OK. Let's take a look at how to fill data with OrderViewModel In the Controller.
public ActionResult List(OrderViewModel orderViewModel, int page = 1) { var pagesize = 10; var count = 0; var orders = _orderService.GetOrders(page, pagesize, model.QueryModel, ref count); orderViewModel.OrderList = new StaticPagedList<OrderModel>(orders, page, pagesize, count); return View(orderViewModel); }
The code in Controller is very simple. It receives two parameters POST. orderViewModel: contains the current page defined by the query parameter Model, page: PagedList.
By the way, let's take a look at the GetOrders () method. The DrapperQueryMultipleIt feels very powerful.
public List<OrderModel> GetOrders(int pageindex, int pagesize, OrderQueryParamModel query, ref int count) { var orders = new List<OrderModel>(); var whereStr = string.Empty; if (query != null) { if (!string.IsNullOrEmpty(query.CustomerName)) { whereStr += string.Format(" and CustomerName like '%{0}%' ", query.CustomerName); } } var cmd = string.Format(@"SELECT COUNT(*) FROM [Orders] WHERE 1=1 {0}; SELECT * FROM ( SELECT *, row_number() OVER (ORDER BY orderId DESC ) AS [row]
FROM [Orders] WHERE 1=1 {0} )t WHERE t.row >@indexMin AND t.row<=@indexMax", whereStr); using (IDbConnection conn = BaseDBHelper.GetConn()) { using (var multi = conn.QueryMultiple(cmd,
new { indexMin = (pageindex - 1) * pagesize, indexMax = pageindex * pagesize })) { count = multi.Read<int>().SingleOrDefault(); orders = multi.Read<OrderModel>().ToList(); } } return orders; }
Note that the order of multi. Read must be the same as that of the data set queried by SQL.
Well, the data is so pleasant to get. Let's take a look at the key front-end data presentation.
1. Add reference in View first
@using PagedList.Mvc;@using PagedList;
@model Models.OrderViewModel
2. Create a form for the query
<Div class = "page-header"> @ using (Html. beginForm ("List", "Order", FormMethod. post, new {id = "OrderForm", @ class = "form-horizontal"}) {@ Html. raw ("customer name:") @ Html. textBoxFor (m => m. queryModel. customerName) @ Html. raw ("Order No.:") @ Html. textBoxFor (m => m. queryModel. orderNo) <button type = "submit" class = "btn-purple btn-sm"> query </button> // queries. Why is this used? <Input type = "hidden" name = "page" value = "1"/>}</div>
3. Bind data
<Table class = "table loading table-bordered margin-top-5 margin-bottom-5"> <thead> <tr> <th> order number </th> <th> customer name </th> <th> mobile phone number </th> <th> commodity quantity </th> <th> order amount </th> <th> order time </th>/ th> </tr> </thead> <tbody> @ foreach (var item in Model. orderList) {<tr> <td> @ item. orderNo </td> <td> @ item. customerName </td> <td> @ item. customerMobile </td> <td> @ item. productQuantity </td> <td> @ item. orderAmount </td> <td> @ item. orderCreateTime </td> </tr >}</tbody> </table>
4. Bind the paging plug-in Data
@if (Model.OrderList != null&&Model.OrderList.Any()){ <div class="pagedList" style="margin:0 auto;text-align:center"> @Html.PagedListPager(Model.OrderList, page => Url.Action("List", new { page }), PagedListRenderOptions.Classic) </div>}
OK, everything is done. Run the command and you will find that the links generated by the paging navigation are in the form of "/Order/List/2". Other query parameters cannot be passed to the Controller.
Let's use another idea. Why don't we put the page parameter in form? Remember that we have a hidden input with name = page in form?
$(function () { $(".pagination > li > a").click(function () { event.preventDefault(); var index = $(this).html(); if (index == '»') { index = parseInt($(".pagination > li[class=active] > a").html()) + 1; } if (index == '«') { index = parseInt($(".pagination > li[class=active] > a").html()) - 1; } if (index < 1) return; $("input[name=page]").val(index); $("#OrderForm").submit(); }); });
Through this section of JS, the tag of the original page is directly voided, and his page value is obtained and put in form, and then the submit () of form is directly triggered (), this satisfies our general query business needs.