Blazor Navigationmanager 取消位置导航已更改

dan*_*era 6 c# navigation .net-core blazor blazor-webassembly

题:

Blazor 有没有办法取消导航?

让我们假设一个a href像这样的 siple :

<a href="/some/other/blazor/spa/page">Go</a>
Run Code Online (Sandbox Code Playgroud)

我想取消导航(例如,如果我们正在编辑表单)

我尝试过的。

通过JS

onbeforeunload通过 JSInterop设置了dom 委托:

window.onbeforeunload = function(){
        return 'Vols abandonar aquesta pàgina?';
      };
Run Code Online (Sandbox Code Playgroud)

但 blazor 绕过它。

通过位置已更改

我尝试拦截locationchanged事件导航失败:

@implements IDisposable
@inject NavigationManager NavigationManager

...

protected override void OnInitialized()
{
    NavigationManager.LocationChanged += HandleLocationChanged;
}

private void HandleLocationChanged(object sender, LocationChangedEventArgs e)
{
    // Cancel Navigation Here
}

public void Dispose()
{
    NavigationManager.LocationChanged -= HandleLocationChanged;
}
Run Code Online (Sandbox Code Playgroud)

Pet*_*ris 5

目前否,此功能正在针对 .NET V5 进行讨论 - 并且有一个社区贡献拉取请求,因此希望能够加入。https://github.com/dotnet/aspnetcore/pull/24417

当您在 Blazor 中导航时,页面不会更改,因此不会进行卸载以触发 onbeforeunload。

  • 不幸的是,看起来这最快要等到.net 7。 (5认同)

tom*_*dox 5

此功能是在 .NET 7 中添加的,可以在“路由和导航”页面的“处理/防止位置更改”部分中找到文档。

该文档中的以下示例显示了处理导航开始(在方法中OnLocationChanging)的代码,然后context.PreventNavigation()在用户尝试导航到计数器页面时取消该导航(使用 ):

NavigationManager Navigation

<p>
    <button @onclick="@(() => Navigation.NavigateTo("/"))">
        Home (Allowed)
    </button>
    <button @onclick="@(() => Navigation.NavigateTo("/counter"))">
        Counter (Prevented)
    </button> </p>

@code {
    private IDisposable? registration;

    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            registration = 
                Navigation.RegisterLocationChangingHandler(OnLocationChanging);
        }
    }

    private ValueTask OnLocationChanging(LocationChangingContext context)
    {
        if (context.TargetLocation == "/counter")
        {
            context.PreventNavigation();
        }

        return ValueTask.CompletedTask;
    }

    public void Dispose() => registration?.Dispose(); } 
Run Code Online (Sandbox Code Playgroud)