In bazor wasm I am making a paginator component, to add pagination to a table component. The paginator component takes an event callback (PageChanged
) which is executed when the user changes the page.
Here is the view
<div id="paginator-container">
<div id="paginator-controls">
<button type="button"
class="btn btn-action"
@onclick="@this.GoToFirstPage"
disabled="@this.IsFirstPage">
<i class="fas fa-angle-double-left"></i>
</button>
<button type="button"
class="btn btn-action"
@onclick="@this.GoToPreviousPage"
disabled="@this.IsFirstPage">
<i class="fas fa-angle-left"></i>
</button>
<span>
page @this.CurrentPage of @this.PageCount
</span>
<button class="btn btn-action"
@onclick="@this.GoToNextPage"
disabled="@this.IsLastPage">
<i class="fas fa-angle-right"></i>
</button>
<button class="btn btn-action"
@onclick="@this.GoToLastPage"
disabled="@this.IsLastPage">
<i class="fas fa-angle-double-right"></i>
</button>
</div>
And the associated code
public partial class Paginator
{
[Parameter]
public int Lenght { get; set; }
[Parameter]
public EventCallback<InnosysPaginatorContext> PageChanged { get; set; }
[Parameter]
public int PageSize { get; set; } = 50;
private int CurrentPage { get; set; }
private int PageCount { get; set; }
private bool IsFirstPage
=> this.CurrentPage == 1;
private bool IsLastPage
=> this.CurrentPage == this.PageCount;
protected override void OnParametersSet()
{
this.SetPageCount();
this.CurrentPage = 1;
base.OnParametersSet();
}
private void SetPageCount()
{
decimal pageCount = (decimal)this.Lenght / this.PageSize;
if (pageCount != Math.Floor(pageCount))
{
pageCount = Math.Floor(pageCount + 1);
}
this.PageCount = (int)pageCount;
}
private async Task GoToFirstPage()
=> await this.GoToPage(1);
private async Task GoToPreviousPage()
=> await this.GoToPage(this.CurrentPage - 1);
private async Task GoToNextPage()
=> await this.GoToPage(this.CurrentPage + 1);
private async Task GoToLastPage()
=> await this.GoToPage(this.PageCount);
private Task GoToPage(int pageIndex)
{
this.CurrentPage = Math.Clamp(pageIndex, 1, this.PageCount);
return this.ExecutePageChangedEvent();
}
private async Task ExecutePageChangedEvent()
=> await this.PageChanged.InvokeAsync(new InnosysPaginatorContext
{
CurrentPage = this.CurrentPage,
PageSize = this.PageSize
});
}
When I use the paginator without setting PageChanged
, like this:
<Paginator Lenght="300" />
I can move through the pages just fine.
However, if I set the callback, like this
<Paginator Lenght="300"
PageChanged="@this.OnPageChangedTest" />
<p>Page: @pageIndex</p>
<p>page size: @pageSize</p>
@code{
int pageIndex = 1;
int pageSize = 50;
void OnPageChangedTest(InnosysPaginatorContext innosysPaginatorContext)
{
pageIndex = innosysPaginatorContext.CurrentPage;
pageSize = innosysPaginatorContext.PageSize;
}
}
The buttons only work once and I can only get to page 2. Subsequent clicks on the buttons for the next page execute the callback, but the CurrentPage
of the paginator is stuck on page 2.
Why does this happen?
this
object is implied, unlike in JS. You don't need to specify it (unless trying to differentiate between a local method-scoped variable and a class value) - Quango