Everything I've read points me to using NavigationManager.LocationChanged event, however that does not detect when only the query string changes. Therefore, nothing fires.
I've tried what is suggested here and that does not do what I am looking for.
I need my component to rerender everytime the query parameters in the current route changes. Has anyone been able to do this?
UPDATE:
Here is my code example:
@page "/accounts"
@if (Accounts != null)
{
<table>
<tbody>
@foreach (var account in Accounts)
{
<tr>
<td>
<NavLink href="/accounts/?accountId={account.AccountId}">@Account.Name</NavLink>
</td>
</tr>
}
</tbody>
</table>
}
@if (Account != null)
{
<div>
<h2>@Account.Name</h2>
</div>
}
@implements IDisposable
@inject NavigationManger NavManager
@inject AccountService AccountService
@code {
protected Guid Id { get; set; } = Guid.NewGid();
protected Guid AccountId { get; set; } = Guid.Empty;
protected List<AccountModel> Accounts { get; set; }
protected AccountModel Account { get; set; }
protected override void OnInitialized()
{
NavManager.LocationChanged += LocationChanged;
}
protected async override Task OnParametersSetAsync()
{
if (AccountId != Guid.Empty)
{
Account = await AccountService.GetAsync(AccountId);
}
else
{
Accounts = await AccountService.GetAllAsync();
}
StateHasChanged();
}
void LocationChanged(object sender, LocationChangedEventArgs e)
{
Id = Guid.NewGuid();
StateHasChanged();
}
void IDisposable.Dispose()
{
NavManager.LocationChanged -= LocationChanged;
}
}
The problem here is LocationChanged(object, LocationChangedEventArgs) does not fire when only the query parameters change. Which makes sense, the route is the same /accounts.
Bascically I have one page to show a list of Accounts and view a single account. I want the route to be /accounts when view the list and '/accounts?accountId=someAccountId' to be the route when im viewing one. Using standard NavLink component does not trigger a rerender of the component and neither does the LocationChanged event. Not even with setting a new Id value. Seeing as to how StateHasChanged only rerenders the component if a value has changed.
I ended up getting what I wanted to happen work like this:
@page "/accounts"
@if (Accounts != null)
{
<table>
<tbody>
@foreach (var account in Accounts)
{
<tr>
<td>
<NavLink href="/accounts/?accountId={account.AccountId}">@Account.Name</NavLink>
</td>
</tr>
}
</tbody>
</table>
}
@if (Account != null)
{
<div>
<h2>@Account.Name</h2>
</div>
}
@implements IDisposable
@inject NavigationManger NavManager
@inject AccountService AccountService
@code {
protected Guid Id { get; set; } = Guid.NewGid();
protected Guid AccountId { get; set; } = Guid.Empty;
protected List<AccountModel> Accounts { get; set; }
protected AccountModel Account { get; set; }
protected override void OnInitialized()
{
NavManager.LocationChanged += LocationChanged;
}
protected async override Task OnParametersSetAsync()
{
if (AccountId != Guid.Empty)
{
Account = await AccountService.GetAsync(AccountId);
}
else
{
Accounts = await AccountService.GetAllAsync();
}
StateHasChanged();
}
async void LocationChanged(object sender, LocationChangedEventArgs e)
{
if (AccountId != Guid.Empty)
{
Account = await AccountService.GetAsync(AccountId);
}
else
{
Accounts = await AccountService.GetAllAsync();
}
StateHasChanged();
}
void IDisposable.Dispose()
{
NavManager.LocationChanged -= LocationChanged;
}
}
I ended up just calling all the same code I want to run on a first render manually. I was hoping (falsely assuming) that I could tell it to just rereun the component lifecycle from the top automatically by changing one local property and then calling StateHasChanged.
Now when I toggle between "/accounts" and "/accounts?accountId=someId" the component rerenders as I want.
I do this in a wasm app works well
set this on your page where you want to receive the route parameter
@page "/pagename/{text?}"
<div>@Text</div>
then
@code {
[Parameter]
public string? Text { get; set; }
protected override void OnInitialized()
{
Text = Text ?? "fantastic";
}
protected override void OnParametersSet()
{
Text = Text ?? "Name Not Supplied";
}
}
The will re-render any data changes, AFAIK you can't force a component to re-render without reloading it, only the changed subscribers, which makes sense, as re-renders are expensive.
Docs look under route parameters
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With