MrJahanbin
MrJahanbin

Reputation: 465

refresh Blazor page

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

Answers (8)

Robin Wilson
Robin Wilson

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

clark wu
clark wu

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

Alexandru Tocan
Alexandru Tocan

Reputation: 61

For me worked this code:

_navigationManager.Refresh();

And insert this on the top of the page

@inject NavigationManager _navigationManager

Upvotes: 6

tapa_
tapa_

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

clamchoda
clamchoda

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

Brian Ganster
Brian Ganster

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.

relevant docs

Upvotes: 8

Mister Magoo
Mister Magoo

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

AliNajafZadeh
AliNajafZadeh

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

Related Questions