J'apprends les pages de base de rasoir asp.net avec ef. Je veux implémenter la pagination avec ma table, j'ai vérifié ce tutoriel
https://docs.Microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-2.1
mais cela ne prend en charge que les versions antérieure et suivante, je fais des recherches depuis longtemps, toutes les solutions sont liées à asp.net core mvc, mais j'utilise des pages de rasoir, il n'y a pas de contrôleur dans mon projet, des idées à mettre en œuvre?
C'est l'effet que je veux implémenter
<form method="get" asp-page="./Index">
<nav aria-label="Page navigation">
<ul class="pagination">
<li>
<a href="#" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
@{
var totalPages = Model.Products.Count % 2 == 0 ? Model.Products.Count / 2 : Model.Products.Count / 2 + 1;
}
@for (int i = 1; i <= totalPages; i++)
{
<li><a asp-page="./Index" asp-route-id="@i">@i</a></li>
}
<li>
<a href="#" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
</form>
cshtml.cs
public async Task OnGetAsync(string sortOrder, string searchString, string shopString, string statusString, int page)
{}
La pagination est relativement simple. Il y a des bibliothèques disponibles pour le faire pour vous, mais j'ai commencé à leur trouver plus de problèmes qu'elles ne valent.
Vous avez besoin de trois informations dans la demande (ou définissez les valeurs par défaut):
Le numéro de page et la taille vous donnent vos valeurs "sauter" et "prendre":
var skip = (page - 1) * size;
var take = size;
Vous pouvez ensuite récupérer les résultats via:
var pageOfResults = await query.Skip(skip).Take(take).ToListAsync();
Où query
est une IQueryable
- soit votre DbSet
directement, soit la DbSet
avec une clause Where
, OrderBy
, etc. appliquée.
Ensuite, il vous suffit de connaître le nombre total d'éléments pour comprendre les pages:
var count = await query.CountAsync();
Pro Tip , vous pouvez paralléliser les deux requêtes (résultats et nombre total) en effectuant:
var resultsTask = query.Skip(skip).Take(take).ToListAsync();
var countTask = query.CountAsync();
var results = await resultsTask;
var count = await countTask;
Les tâches retournent à chaud ou ont déjà commencé. Le mot clé await
conserve simplement la suite du reste du code jusqu'à la fin de la tâche. En conséquence, si vous attendez chaque ligne, elles seront terminées en série, mais si vous commencez les deux, d'abord, puis attendez chacune, elles seront traitées en parallèle.
Quoi qu'il en soit, une fois que vous avez le compte:
var totalPages = (int)Math.Ceil(Decimal.Divide(count, size));
var firstPage = 1;
var lastPage = totalPages;
var prevPage = Math.Max(page - 1, firstPage);
var nextPage = Math.Min(page + 1, lastPage);
Remarque: vous pouvez déterminer si les boutons premier/précédent et dernier/suivant doivent être affichés en fonction de leur valeur respective firstPage
ou lastPage
.
Ensuite, construisez vous-même un modèle avec ces informations et vous pouvez l’envoyer à la vue pour afficher les résultats et générer le code HTML de pagination.
Vous pouvez utiliser le package JW.Pager
NuGet ( https://www.nuget.org/packages/JW.Pager/ )
Voici un exemple de modèle de page de pages de rasoir qui pagine une liste de 150 éléments:
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc.RazorPages;
using JW;
namespace RazorPagesPagination.Pages
{
public class IndexModel : PageModel
{
public IEnumerable<string> Items { get; set; }
public Pager Pager { get; set; }
public void OnGet(int p = 1)
{
// generate list of sample items to be paged
var dummyItems = Enumerable.Range(1, 150).Select(x => "Item " + x);
// get pagination info for the current page
Pager = new Pager(dummyItems.Count(), p);
// assign the current page of items to the Items property
Items = dummyItems.Skip((Pager.CurrentPage - 1) * Pager.PageSize).Take(Pager.PageSize);
}
}
}
Et voici la page de rasoir contenant le code HTML pour les contrôles de liste paginée et de pageur:
@page
@model RazorPagesPagination.Pages.IndexModel
<!-- items being paged -->
<table class="table table-sm table-striped table-bordered">
@foreach (var item in Model.Items)
{
<tr>
<td>@item</td>
</tr>
}
</table>
<!-- pager -->
@if (Model.Pager.Pages.Any())
{
<nav class="table-responsive">
<ul class="pagination justify-content-center d-flex flex-wrap">
@if (Model.Pager.CurrentPage > 1)
{
<li class="page-item">
<a class="page-link" href="/">First</a>
</li>
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.CurrentPage - 1)">Previous</a>
</li>
}
@foreach (var p in Model.Pager.Pages)
{
<li class="page-item @(p == Model.Pager.CurrentPage ? "active" : "")">
<a class="page-link" href="/?p=@p">@p</a>
</li>
}
@if (Model.Pager.CurrentPage < Model.Pager.TotalPages)
{
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.CurrentPage + 1)">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="/?p=@(Model.Pager.TotalPages)">Last</a>
</li>
}
</ul>
</nav>
}
Pour plus de détails, j'ai posté un tutoriel complet avec un exemple de projet à http://jasonwatmore.com/post/2018/10/15/aspnet-core-razor-pages-pagination-example
J'ai fait cette mise en œuvre en mélangeant quelques réponses sur le sujet, j'espère que cela aidera quelqu'un.
Ajoutez une classe PagedResultBase
(que vous pouvez étendre en ajoutant les autres propriétés dont vous avez besoin):
public abstract class PagedResultBase
{
public int CurrentPage { get; set; }
public int PageCount { get; set; }
public int PageSize { get; set; }
public int RowCount { get; set; }
}
Ajouter une classe PagedResult
:
public class PagedResult<T> : PagedResultBase where T : class
{
public ICollection<T> Results { get; set; }
public PagedResult()
{
Results = new List<T>();
}
}
Ajoutez une IQueryableExtensions
avec une extension GetPagedResult
:
public static class IQueryableExtensions
{
public async static Task<PagedResult<T>> GetPagedResultAsync<T>(this IQueryable<T> query, int currentPage, int pageSize) where T : class
{
var skip = (currentPage - 1) * pageSize;
var take = pageSize;
var rowCount = await query.CountAsync();
var results = await query.Skip(skip).Take(take).ToListAsync();
var pagedResult = new PagedResult<T> {
CurrentPage = currentPage,
PageCount = (int)Math.Ceiling(decimal.Divide(rowCount, pageSize)),
PageSize = pageSize,
RowCount = rowCount,
Results = results
};
return pagedResult;
}
}
Vous avez terminé:
var pagedResult = await MyContext.Posts.Where(p => p.Featured == true).GetPagedResultAsync(1, 10);
J'ai créé un taghelper de pagination pour .net Core Razor Pages. Il peut être configuré dans des balises html ou dans appsettings.json pour afficher/masquer les boutons précédent-suivant, premier-dernier, le nombre maximal de pages affichées et d'autres paramètres de personnalisation,
Le projet est disponible pour l'installation en tant que package Nuget (et github):
Install-Package LazZiya.TagHelpers -Version 1.0.2
Voir les étapes d'installation ici: http://ziyad.info/fr/articles/21-Paging_TagHelper_for_ASP_NET_Core
Démo en direct et tous les paramètres: http://demo.ziyad.info/en/paging
L'utilisation de appsettings.json pour les configurations de pagination vous aidera à avoir un code HTML plus propre et vous donnera la possibilité de modifier les paramètres de pagination de tous les taghelpers de pagination ou de ceux spécifiques de votre application.