ASP.NET MVC Pager based on Generic and Constraint Interfaces
I have in my site a lot of various implementation Generic in practice, for example Generic VB.NET function for loading ExcelFile to DataBase (EF6 CodeFirst) with Reflection and avoiding Linq-to-Entity Linq.Expressions (use Linq-to-Object IEnumerable), but in this page I want to describe solution impossible to realize without generic at all.
Look to the screens below, please. All pager in my current project has one pager. But how is possible? It's obvious that dataStructure in each page is different.
In fact each page use this Partial View, and how is possible to use in string 16 the same name DataListT? And how this View can manipulate from so different structure (Location, Trip, City, AirportRate and so on)?
1: <nav aria-label="Trip Navigation">
2: <ul Class="pagination justify-content-center">
3: <li id="page-first" Class="page-item">
4: @Html.ActionLink("First", "Index", Nothing, New With {.Class = "page-link text-danger", .onclick = "ShowWaitGif(event)"})
5: </li>
6: <li id="page-previous" Class="page-item">
7: @If Model.Skip > 0 Then
8: @Html.ActionLink("Previous", "Previous", New With {.id = Model.Skip}, New With {.Class = "page-link text-danger", .onclick = "ShowWaitGif(event)"})
9: End If
10:
11: </li>
12: <li Class="page-item">
13: <span style="padding-top:5px;display:table-cell;"> (@Model.PagerText)</span>
14: </li>
15: <li id="page-next" Class="page-item">
16: @If Model.Skip + 10 < Model.DataListT.Total Then
17: @Html.ActionLink("Next", "Next", New With {.id = Model.Skip}, New With {.Class = "page-link text-danger", .onclick = "ShowWaitGif(event)"})
18: End If
19: </li>
20: </ul>
21: </nav>
All page use this pager.
The common and simple answer is Generic. I have a lot of various articles about Generic, for example Generic VB.NET function for loading ExcelFile to DataBase (EF6 CodeFirst) with Reflection and avoiding Linq-to-Entity Linq.Expressions (use Linq-to-Object IEnumerable).
But simple using generic is not enough in this case. For successfully manipulation this data structure we need more than simple Generic, because we need in shallow the same interfaces but deeper we need difference, but similar interface. This future named Constraint.
So, first interface is simple, its placed deeper and it describe all our dataStructure we received from backend.
1: Public Interface IListTotal(Of X)
2: Property DataList As IEnumerable(Of X)
3: Property Total As Integer
4: End Interface
All data we receiving from backend will be in the same format.
And all dataStructure with communication to backend Implements interface IListTotal.
But this is basic simplest idea of Interface and Implements and this simple idea don't help as to organize pager.
To organize Pager we need to create universal (generic) data structure OVER this simple structures we receive from backend.
In this case we need to create new data structure over this simple structures (Implemented from IListTotal) and load to new structure current elementary structure as Constraint.
And this is answer how is possible.
1: Public Interface IPagerModel(Of T As IListTotal(Of X), X)
2: Property DataListT As T
3: Property Skip As Integer
4: Property PagerText As String
5: Property Err1 As String
6: End Interface
As a result we can load to page this four model organized by similar way (DataListT, Skip, PagerText, Err1).
And this allow us upload to page different model.
But any model can be manipulated by similar way, by the same code.
This is a way to create universal pager code to whole project.
|