After completing the addition, deletion, modification and query of the task list, let’s talk about the essential paging function.
First of all, I’m glad ABP has helped us encapsulate the paging implementation. It’s really considerate.
In this section, let’s take a look at how to use ABP for paging.
1. Paging request dto definition
Data transfer objects are used for data transfer of application layer and presentation layer.
The presentation layer passes in a data transfer object (dto) to call an application service method, and then the application service executes some specific business logic through the domain object and returns the dto to the presentation layer. In this way, the presentation layer and domain layer are completely separated. In an application with good layering, the presentation layer does not directly use domain objects (warehouses, entities).
When there is a paging request in the presentation layer, we generally need to specify two parameters, one is to mark the page and the other is the number of lines per page (generally configured with a configuration file).
Because paging is a very common function, when we have paging requests in the presentation layer, we’d better have corresponding DTOs to encapsulate these two parameters.
The ABP source code does not encapsulate such a common class for us, but in the abpzero project, the corresponding paging dto is defined.
The corresponding class diagram is as follows:
Page sorting and filtering corresponding dto class diagram
It can be seen that it mainly includes the following four public dto definitions:
- Pagedinputdto: paging request dto
- Pagedandsortedinputdto: page sorting dto
- Pagedsortedandfilteredinputdto: paging sort filter dto
- Pagedandfilteredinputdto: page filter dto
Is it very practical? Our paging is generally mixed with filtering and sorting.
The following main attributes are defined:
- Maxresultcount: the number of rows per page, which can be read from the defined configuration.
- Skipcount: jump quantity. The general calculation formula is skipcount = Page * maxresultcount (pages * rows).
- Filter: filter string
- Sorting: sorting by
The specific implementation will not be detailed. I believe that if you look at the class diagram carefully, you can implement it yourself. Abpzero defines these public DTOs in the dto folder of the application service layer. The specific path is shown in the figure below.
2. How to use paging dto
Take our task list as an example. We modify it and create itGetTaskInputDto
, let it inherit fromPagedSortedAndFilteredInputDto
, soGetTaskInputDto
You have the properties required for paging sorting and filtering.
public class GetTasksInput : PagedSortedAndFilteredInputDto
{
public TaskState? State { get; set; }
public int? AssignedPersonId { get; set; }
}
3. Return paging result dto
ABP has defined a generic pagedresultdto for us to wrap the returned paging results. It mainly includes two attributes: int totalcount saves the total number, and ireadonlylist < T > items saves the returned paging result set.
4. Application service layer paging logic implementation
1. Define the interface in itaskappservice
PagedResultDto<TaskDto> GetPagedTasks(GetTasksInput input);
2. Implement the interface in taskappservice:
public PagedResultDto<TaskDto> GetPagedTasks(GetTasksInput input)
{
//Preliminary filtration
var query = _taskRepository.GetAll().Include(t => t.AssignedPerson)
.WhereIf(input.State.HasValue, t => t.State == input.State.Value)
.WhereIf(!input.Filter.IsNullOrEmpty(), t => t.Title.Contains(input.Filter))
.WhereIf(input.AssignedPersonId.HasValue, t => t.AssignedPersonId == input.AssignedPersonId.Value);
//Sort
query = !string.IsNullOrEmpty(input.Sorting) ? query.OrderBy(input.Sorting) : query.OrderByDescending(t => t.CreationTime);
//Get total
var tasksCount = query.Count();
//Default paging mode
//var taskList = query.Skip(input.SkipCount).Take(input.MaxResultCount).ToList();
//ABP provides the extension method pageby paging mode
var taskList = query.PageBy(input).ToList();
return new PagedResultDto<TaskDto>(tasksCount,taskList.MapTo<List<TaskDto>>());
}
The implementation of paging is very simple. First filter, sort, and then paging. Finally, pagedresultdto is used to encapsulate the paging results.
Carefully, you may find two methods that have not been used in LINQWhereIf
andPageBy
Yes, this is the extension method provided by ABP. Those interested can see the source codeQueryableExtensions
The specific implementation of LINQ is actually very simple, but we may not think of it when using LINQ.
Here are some questions:
How many queries have been made in this code?
What paging technology is used in the code? (true paging? False paging?)
5. Use x.pagedlist for front-end paging
In ASP Net MVC has a series of open source implementations for front-end paging, and the open source X. pagedlist paging is used in my demo. For specific source code, please refer to X. pagedlist GitHub.
1. Please install x.pagedlist.xml in your web project yourself MVC nuget package
X.PagedList. MVC nuget package
2. Use the method provided by X. pagedlist in the controller to construct paging results for front-end use
Because we have manually implemented paging logic in the application service layer, we need to construct staticpagedlist as the return result according to the example on the official website of X. pagedlist.
public ActionResult PagedList(int? page)
{
//Lines per page
var pageSize = 5;
var pageNumber = page ?? 1;// What page
var filter = new GetTasksInput
{
Skipcount = (PageNumber - 1) * PageSize, // number ignored
MaxResultCount = pageSize
};
var result = _taskAppService.GetPagedTasks(filter);
//The paging logic has been completed manually in the application service layer, so the paging results need to be constructed manually
var onePageOfTasks = new StaticPagedList<TaskDto>(result.Items, pageNumber, pageSize, result.TotalCount);
//Put the paging results into viewbag for view to use
ViewBag.OnePageOfTasks = onePageOfTasks;
return View();
}
From the code, we can see that after constructing the paging results provided by X. pagedlist, we put them into the viewbag for the view.
3. Add paging control to view
The code of pagedlist view is as follows:
@using X.PagedList.Mvc;
@using Abp.Web.Mvc.Extensions
@using X.PagedList;
<link href="~/Content/PagedList.css" rel="external nofollow" rel="stylesheet" />
<ul>
@foreach (var task in ViewBag.OnePageOfTasks)
{
<li>
<div>
<button type="button">Edit</button>
<button type="button">Delete</button>
</div>
<div>
<a href="#" rel="external nofollow" >
@*<i></i>*@
</a>
<div>
<h4>@task.Title</h4>
<span>@task.CreationTime.ToString("yyyy-MM-dd HH:mm:ss")</span>
</div>
</div>
</li>
}
</ul>
@Html.PagedListPager((IPagedList)ViewBag.OnePageOfTasks, page => Url.Action("PagedList", new { page }))
The last sentence of the code is used to generate paging controls.
The final effect is shown in the figure:
summary
summary
This section mainly explains how to use ABP for background paging, and also explains the implementation of ABP background paging logic. It also demonstrates how to use X. pagedlist for front-end paging.