Reputation: 465
In the Blazer Server Side project with .NET 6, I am on the following page:
https: //localhost: 7252/Product/a3620f82-7cba-473c-9273-1cf300a181eb
I have a NavLink on this page that points to the exact same URL above. But when I click on the method, the page does not show any reaction and does not refresh or update. What should I do?
Sample my codes:
@page "/Product/{Id:guid}"
@using Application.ProductGalleries.Queries
@using Application.Products.Queries
@using ViewModels.ProductVariants
@using ViewModels.ProductVariantsDetails
@using ViewModels.Products
<div class="col-12 px-0">
<h1>
<NavLink href="@($"/Product/a3620f82-7cba-473c-9273-1cf300a181eb")">@Model.ProductName</NavLink>
</h1>
<p>دسته بندی : @Model.CategoryName<span> برند: @Model.BrandName</span></p>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><NavLink href="/">صفحه نخست</NavLink></li>
<li class="breadcrumb-item"><NavLink href="/Products">@Model.CategoryName</NavLink></li>
<li class="breadcrumb-item active" aria-current="page">@Model.BrandName</li>
</ol>
</nav>
</div>
@code {
[Parameter]
public Guid Id { get; set; }
protected override Task OnParametersSetAsync()
{
return base.OnParametersSetAsync();
}
protected override Task OnAfterRenderAsync(bool firstRender)
{
return base.OnAfterRenderAsync(firstRender);
}
protected override bool ShouldRender()
{
return base.ShouldRender();
}
protected override void OnAfterRender(bool firstRender)
{
base.OnAfterRender(firstRender);
}
protected override void OnInitialized()
{
base.OnInitialized();
}
protected override void OnParametersSet()
{
base.OnParametersSet();
}
public override Task SetParametersAsync(ParameterView parameters)
{
return base.SetParametersAsync(parameters);
}
protected async override Task OnInitializedAsync()
{
var request = new GetProductByIdQuery() { ProductId = Id };
var product = await Mediator.Send(request: request);
if (product.Value != null)
{
Model = product.Value;
GalleryModel = await GetGallery();
}
}
}
During the search, if the user has searched for bananas and is on the search page and wants to search for bananas again, the page will not show any reaction. I went through all the life cycle overrides to see where it was going but it didn't react.
I also thought of using StateHasChanged (). But my code is a NavLink and where should I put this code when the project does not enter the life cycle?
Upvotes: 29
Views: 57082
Reputation: 390
This is what I came up with based on a combination of the examples above where each hyperlink is passed through an intermediary page where the URL is then forwarded on but this does not force the browser to refresh the entire page and the back button does work although perhaps not 100% of the time it seems:
Name of page: LoadPage.razor
Required URL: /Shop/Guildford
URL to call: /LoadPage/Shop/Guildford
Code for intermediary page is below, then just add /LoadPage
at the start of each URL where the page needs to reload data when parameters change:
@page "/LoadPage/{*url}"
@inject NavigationManager _navigationManager
<h3>Loading...</h3>
@code {
[Parameter]
public string? url { get; set; }
protected override void OnParametersSet()
{
_navigationManager.NavigateTo(url ?? "", false, true);
}
}
So where pages suffer the issue of not refreshing when parameters change (e.g. /Shop/Guildford
to /Shop/London
then it just involves adding /LoadPage
at the start of each link.
Upvotes: 0
Reputation: 426
This works fine for me so far and doesn't pollute the URL fallback history.
@inject NavigationManager NavigationManager
<Link To="#" Clicked="()=>ToReload(somelink)"></Link>
@code {
private async Task ToReload(string link)
{
NavigationManager.NavigateTo("ToReload");
NavigationManager.NavigateTo(link, replace: true);
}
}
Upvotes: 0
Reputation: 61
For me worked this code:
_navigationManager.Refresh();
And insert this on the top of the page
@inject NavigationManager _navigationManager
Upvotes: 6
Reputation: 306
You actually need to NavigateTo your current Uri with force load. I use simple extension method for this
public static void ReloadPage(this NavigationManager manager)
{
manager.NavigateTo(manager.Uri, true);
}
Upvotes: 29
Reputation: 4991
I wanted to avoid the overridden NavigateTo
with forceLoad
set to true due to reloading the session and flickering the page.
The solution was simply an empty page that took a url as a parameter while immediately redirecting. This means it also works when reloading the current page. The trick is to use HttpUtility.UrlEncode
when setting the parameter.
ForceLoader.razor
@page "/forceloader/{navigationUrl}"
@code {
[Parameter]
public string navigationUrl { get; set; }
[Inject] private NavigationManager _navigationManager { get; set; }
protected override void OnInitialized()
{
_navigationManager.NavigateTo(navigationUrl);
}
}
Implementation
_navigationManager.NavigateTo($"/forceloader/{System.Web.HttpUtility.UrlEncode(navigationUrl)}");
The only caveat I can think of is history control. After using the ForceLoader
you would need to call javascript:history.go(-2)
instead of javascript:history.back()
.
Upvotes: 6
Reputation: 81
Building on AliNajafZadeh's answer:
@inject NavigationManager _navigationManager
...
<a href="" @onclick="@NevigateToYourUrl" @onclick:preventDefault />
...
@code
{
void NevigateToYourUrl()
{
_navigationManager.NavigateTo("YourPagePath", true);
}
}
Setting the second parameter to true bypasses client-side routing and forces the browser to load the new page from the server.
Upvotes: 8
Reputation: 9029
Without knowing what "During the search" means - you haven't shown the search - I would say using a NavLink to refresh the current page is the wrong choice - use a button to perform an action that doesn't change the current location.
However, if you really must use a NavLink, just add an @onclick
handler to it that calls your data load method.
<NavLink href=@($"/Product/{Id}") @onclick=GetProductData>@Model.ProductName</NavLink>
protected async override Task OnInitializedAsync()
{
await GetProductData();
}
protected async Task GetProductData()
{
var request = new GetProductByIdQuery() { ProductId = Id };
var product = await Mediator.Send(request: request);
if (product.Value != null)
{
Model = product.Value;
GalleryModel = await GetGallery();
}
}
Upvotes: 2
Reputation: 1328
Try following code:
@code {
void NevigateToYourUrl()
{
_navigationManager.NavigateTo("YourPagePath");
}
}
and also you need to inject NavigationManager as follow:
@inject NavigationManager _navigationManager
Try:
<a href="" @onclick="@NevigateToYourUrl" @onclick:preventDefault />
Upvotes: 12