Wyobraźcie sobie sporą aplikacje. Nie jakiegoś giganta, jednak liczę, że przed waszymi oczami pojawi się solidny obraz. Potraficie ją sobie wyimaginować bez paginacji wyników? Osobiście uważam, że każda aplikacja zaopatrzona w listę wyników powinna zawierać mechanizm paginacji. Prezentowanie użytkownikowi tysięcy wyników na jednym ekranie nie jest ani wygodne, ani nie wygląda najlepiej. Dlatego też, w dzisiejszym, dość krótkim, artykule chce wam pokazać jak zrobić paginowalną listę wyników w aplikacji .NET Core MVC za pomocą paczki X.PagedList.
Konfiguracja
Paczka X.PagedList jest forkiem PagedList. Możemy ja wykorzystywać zarówno w aplikacji .NET Core jak i w samym .NET Framework. My skupimy się tylko na samym .NET Core. Zaczynamy od dodania "X.PagedList.Mvc.Core" do naszego projektu. Czy zrobimy to za pomocą .Net CLI, czy zainstalujemy ją za pomocą naszego IDE nie ma większego znaczenia. Ważne jest, aby w pliku *.csproj pojawiła się poniższa linijka xml-a:
<PackageReference Include="X.PagedList.Mvc.Core" Version="7.2.4" />
Wykorzystanie w kontrolerze
By móc korzystać z tej paczki potrzebujemy struktury danych, która implementuje interfejs "IQueryable". Paczka X.PagedList rozszerza za pomocą mechanizmu "extension methods" interfejs o swoje dodatkowe metody. Jak to robimy? W większości wypadków, jeśli korzystamy z list, kolekcji czy Entity Framework-a, wystarczy wywołać metodę "AsQueryable" na takiej strukturze danych. Pozwala to wykorzystać metody "Skip" i "Take" z LINQ do pobierania aktualnego przedziału danych.
Mając strukturę danych implementującą interfejs "IQueryable" możemy wykorzystać metodę "ToPagedListAsync" do otrzymania listy wyników. Oczywiście, w najprostszym rozwiązaniu, numer strony, na której się znajdujemy, będzie podawany za pomocą "queryString" czyli tej części url-a po znaku: "?". Wynik wywołania tej metody możemy od razu przekazać jako model do widoku. Ewentualnie, możemy wykorzystać ViewBag-a, jednak polecam przekazywanie takich danych jako model. Pozwala to na zachowanie silnego typowania w widoku.
public async Task<IActionResult> Index(int? page)
{
var events = _eventsRepository.Get();
var pageNumber = page ?? 1;
var perPage = 25;
var onePageOfEvents = await events.ToPagedListAsync(pageNumber, perPage);
return View(onePageOfEvents);
}
W widoku, gdzie wykorzystujemy mechanizm templat-ów razor, możemy ustawić model jako typ: "IPagedList". Unikamy w ten sposób całego namespace-a, gdzie znajduje się IPagedList. W sumie, możemy dodać dwa namespace-y: "X.PagedList" i "X.PagedList.Mvc.Core", otrzymując do dyspozycji metodę pomocniczą do wygenerowania kodu html paginacji (@Html.PagedListPager).
Po naszym przekazanym modelu poruszamy się za pomocą pętli foreach, gdzie w pojedynczym obrocie pętli otrzymamy nasz pojedynczy obiekt danego typu.
Cały kod widoku wygląda wtedy następująco.
@model IPagedList<Event>
@using X.PagedList;
@using X.PagedList.Mvc.Core
<ul>
@foreach (var evt in Model)
{
<li>
<a href="/event/details/@evt.Id">@evt.Name</a>
</li>
}
</ul>
@Html.PagedListPager(Model, page => Url.Action("Index", new { page }) )
Podsumowanie
Pokrótce opisałem jak prosto i bez większych komplikacji stworzyć paginacje. Może nie tak proste jak zalanie kakałka mlekiem, ale dla Was, moi drodzy czytelnicy, bułka z masłem. Wystarczy tylko prawidłowo dobrać narzędzie do pracy i wszystko idzie bezproblemowo.
Dzięki za przeczytanie artykułu. Do następnego!