【问题标题】:Blazor WebAssembly App - Warn user on navigation - warn user before leaving web page with unsaved changesBlazor WebAssembly 应用程序 - 在导航时警告用户 - 在离开网页之前警告用户未保存的更改
【发布时间】:2021-05-17 21:38:00
【问题描述】:

我在wwwroot - index.html 中实现了以下代码:

"use strict";
(() => {
const modified_inputs = new Set;
const defaultValue = "defaultValue";
// store default values
addEventListener("beforeinput", (evt) => {
    const target = evt.target;
    if (!(defaultValue in target || defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ("" + (target.value || target.textContent)).trim();
    }
});
// detect input modifications
addEventListener("input", (evt) => {
    const target = evt.target;
    let original;
    if (defaultValue in target) {
        original = target[defaultValue];
    } else {
        original = target.dataset[defaultValue];
    }
    if (original !== ("" + (target.value || target.textContent)).trim()) {
        if (!modified_inputs.has(target)) {
            modified_inputs.add(target);
        }
    } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
    }
});
// clear modified inputs upon form submission
addEventListener("submit", (evt) => {
    modified_inputs.clear();
    // to prevent the warning from happening, it is advisable
    // that you clear your form controls back to their default
    // state with evt.target.reset() or form.reset() after submission
});
// warn before closing if any inputs are modified
addEventListener("beforeunload", (evt) => {
    if (modified_inputs.size) {
        const unsaved_changes_warning = "Changes you made may not be saved.";
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
    }
});
})();

来源:

https://stackoverflow.com/a/48238659/3850405

如果我在不使用 Blazor 导航的情况下尝试关闭选项卡、重新加载或离开网站,这将非常有效。

我想做的是能够从这些类型的导航事件中捕获事件:

Navigation.NavigateTo("/");

<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
    <span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>

<MatButtonLink Href="/" Raised="true">Test navigation</MatButtonLink>

我的示例测试代码:

@page "/editor"
@using Markdig;
@inject NavigationManager Navigation


<div class="row">
    <div class="col-6">
        <textarea class="form-control" @bind-value="Body" @bind-value:event="oninput"></textarea>
        <MatButtonLink Href="/" Raised="true">Test navigation</MatButtonLink>
        <button @onclick="Navigate">
            Test navigation 2
        </button>
    </div>
    <div class="col-6">
        @if (!string.IsNullOrWhiteSpace(Body))
        {
            @((MarkupString)Preview)
        }
    </div>
</div>

@code {
    public string Body { get; set; }

    public string Preview => Markdown.ToHtml(Body);

    private void Navigate()
    {
        Navigation.NavigateTo("/");

    }
}

【问题讨论】:

标签: javascript c# blazor blazor-webassembly matblazor


【解决方案1】:

发现了一个类似的问题,试过window.onbeforeunload

Blazor Navigationmanager cancel navigation on locationchanged

目前似乎没有解决此问题的方法,但为 .NET 6.0 提交了 NavigationManger 的位置更改事件。我希望可以在应用程序的全局级别上捕获此事件。

https://github.com/dotnet/aspnetcore/issues/14962

【讨论】:

    【解决方案2】:

    总结
    从 .NET 5 开始,使用 Blazor 没有方便的方法来执行此操作:捕获单击/鼠标事件或使用 JS。


    您可以通过NavigationManager.LocationChanged订阅这些事件:

    [Inject]
    NavigationManager Navigation { get; set; }
    
    protected override OnInitialized() {
        Navigation.LocationChanged += Handler; // make sure you unsubscribe in a Dispose method
    }
    
    private void Handler(LocationChangedEventArgs args) {
        // Handle navigation event here
    }
    

    请注意,您无法拦截/阻止这些导航事件(目前):您需要拦截点击/鼠标事件才能在 c# 中实现这一点。这并不理想,但您需要执行以下操作:

    <NavLink class="nav-link" 
             href="" 
             Match="NavLinkMatch.All"
             @onclick:preventDefault="shouldPreventDefault">
        <span class="oi oi-home" aria-hidden="true"></span> Home
    </NavLink>
    

    shouldPreventDefault 是一个布尔值,可能由某个作用域状态或服务提供。

    在 JS 中,可能就像监听点击事件一样简单,例如:

    document.addEventListener('click', (e) => {
        // shouldPreventDefault set when this behavior is desirable, 
        // e.g. when changes are unsaved.
        if (shouldPreventDefault && e.target instanceof HTMLAnchorElement) {
            e.preventDefault();
            // etc....
        }
    }
    

    【讨论】:

    • 谢谢,但整个想法是在用户未保存更改时防止事件发生
    猜你喜欢
    • 2019-06-18
    • 2016-06-25
    • 1970-01-01
    • 2017-12-30
    • 2019-03-21
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多