.NET 8 Blazor WebAssembly页面导航时如何重置勾选框状态?
问题描述
我创建了一个.NET 8.0 Blazor Web应用解决方案,Web项目包含以下代码:
Web项目文件
App.razor
<!DOCTYPE html> <html lang="en-GB"> <head> <base href="/"/> <title>My Awesome Web Application</title> <HeadOutlet/> </head> <body> <Routes/> <script src="_framework/blazor.web.js"></script> </body> </html>
Layout.razor
@using myawesomeproject.shared.components @inherits LayoutComponentBase <Header @rendermode="InteractiveWebAssembly"/> @Body
Myawesomehomepage.razor
@page "/" <h1>Home page</h1>
Myawesomepage.razor
@page "/myawesomepage" <h1>My awesome page</h1>
Myotherawesomepage.razor
@page "/myawesomeotherpage" <h1>My awesome other page</h1>
共享组件项目文件
Header.razor
<header> <input @bind="ticked" type="checkbox" role="button"/> <nav> <ul> <li><a href="/">Home</a></li> <li><a href="/myawesomepage">My awesome page</a></li> <li><a href="/myawesomeotherpage">My awesome other page</a></li> </ul> </nav> </header> @code { private bool? ticked = false; protected override void OnInitialized() { ticked = null; StateHasChanged(); } }
Layout组件包含Header组件,Header以InteractiveWebAssembly模式渲染。点击Header中的超链接导航到新的服务器Razor页面时,页面仍包含Layout和Header,但勾选框会保留导航前的勾选状态,即使OnInitialized里设置了ticked = null也无效。现需实现导航到新服务器页面时,自动将勾选框设为未勾选状态。
解决方案
问题核心在于:InteractiveWebAssembly模式的组件会在客户端保留实例状态,OnInitialized仅在组件首次加载时执行,后续导航不会触发重新初始化。要重置勾选状态,需监听导航事件来触发状态更新。
方法一:组件内监听导航事件(推荐)
直接在Header组件中注入NavigationManager,订阅导航变化事件,每次导航完成后重置勾选状态:
@inject NavigationManager NavManager <header> <input @bind="ticked" type="checkbox" role="button"/> <nav> <ul> <li><a href="/">Home</a></li> <li><a href="/myawesomepage">My awesome page</a></li> <li><a href="/myawesomeotherpage">My awesome other page</a></li> </ul> </nav> </header> @code { private bool? ticked = false; private IDisposable? _navigationSubscription; protected override void OnInitialized() { // 订阅导航完成事件 _navigationSubscription = NavManager.LocationChanged += OnLocationChanged; // 初始化时重置状态 ResetCheckboxState(); } private void OnLocationChanged(object? sender, LocationChangedEventArgs e) { // 每次导航后重置勾选框 ResetCheckboxState(); } private void ResetCheckboxState() { ticked = false; StateHasChanged(); } public void Dispose() { // 取消订阅避免内存泄漏 _navigationSubscription?.Dispose(); } }
方法二:通过Layout传递导航状态
若需在Layout层面统一控制多个组件状态,可在Layout中监听导航事件,通过参数通知Header重置:
- 修改Layout.razor:
@using myawesomeproject.shared.components @inherits LayoutComponentBase @inject NavigationManager NavManager <Header @rendermode="InteractiveWebAssembly" IsNavigating="@_isNavigating"/> @Body @code { private bool _isNavigating; protected override void OnInitialized() { NavManager.LocationChanged += (s, e) => { _isNavigating = true; StateHasChanged(); // 延迟重置标记,确保Header已处理状态更新 Task.Delay(100).ContinueWith(_ => { _isNavigating = false; StateHasChanged(); }); }; } }
- 修改Header.razor接收参数:
<header> <input @bind="ticked" type="checkbox" role="button"/> <nav> <ul> <li><a href="/">Home</a></li> <li><a href="/myawesomepage">My awesome page</a></li> <li><a href="/myawesomeotherpage">My awesome other page</a></li> </ul> </nav> </header> @code { [Parameter] public bool IsNavigating { get; set; } private bool? ticked = false; protected override void OnParametersSet() { if (IsNavigating) { ticked = false; StateHasChanged(); } } }
关键说明
- 方法一独立性更强,Header组件自行处理导航状态,无需依赖Layout逻辑。
- 方法二适合需要统一管理多个组件状态的场景。
- 两种方案均利用
NavigationManager.LocationChanged事件,该事件会在所有导航(包括服务器页面导航)完成后触发,确保状态及时重置。
内容的提问来源于stack exchange,提问作者sanepete
相关产品推荐
相关产品推荐

