Blazor ASP.NET Core 8如何在导航变更时触发OnInitializedAsync?
解决方案
方案1:提取逻辑到独立方法,订阅LocationChanged事件
把OnInitializedAsync里的业务逻辑抽成单独的异步方法,在组件初始化时订阅NavigationManager的LocationChanged事件,每次导航变更时调用该方法。记得在组件销毁时取消订阅,避免内存泄漏。
修改后的代码示例:
private IDisposable? _navigationSubscription; private readonly NavigationManager _navigationManager; private readonly IDocumentCacheService _documentCacheService; // 通过构造函数注入依赖服务 public YourComponent(NavigationManager navigationManager, IDocumentCacheService documentCacheService) { _navigationManager = navigationManager; _documentCacheService = documentCacheService; } protected override async Task OnInitializedAsync() { // 首次加载执行数据逻辑 await LoadDocumentsAsync(); // 订阅导航变更事件 _navigationSubscription = _navigationManager.LocationChanged += OnLocationChanged; } private async void OnLocationChanged(object? sender, LocationChangedEventArgs e) { // 导航切换时重新加载数据 await LoadDocumentsAsync(); // 通知组件更新UI(事件线程可能非UI线程) await InvokeAsync(StateHasChanged); } private async Task LoadDocumentsAsync() { Uri uri = new(_navigationManager.Uri); int dataSourceID = 0; switch (uri.Segments[1].ToLower()) { case "planter/": dataSourceID = 1068; break; case "kvaeg/": dataSourceID = 1067; break; case "maskiner/": dataSourceID = 1069; break; case "business/": dataSourceID = 1142; break; } DocumentFilter documentFilter = new() { DataSourceID = dataSourceID, WebSiteID = 16, ShowInFeed = true, ForceDataSourceUpdate = false }; ResponseDTO<IReadOnlyCollection<DocumentListDTO>> responseDTO = await _documentCacheService.GetDocumentsAsync($"DataSource{dataSourceID}", documentFilter); // 将responseDTO数据赋值给组件绑定属性,更新UI } public void Dispose() { // 取消订阅释放资源 _navigationSubscription?.Dispose(); }
方案2:利用路由参数触发OnParametersSetAsync
如果你的组件是路由组件(带@page指令),可以为四个路径分别设置路由,每次导航切换路径时,OnParametersSetAsync会自动触发,直接在这里执行数据加载逻辑即可。
示例代码:
@page "/planter" @page "/kvaeg" @page "/maskiner" @page "/business" @inject NavigationManager NavigationManager @inject IDocumentCacheService DocumentCacheService <!-- 组件UI内容 --> @code { protected override async Task OnParametersSetAsync() { await LoadDocumentsAsync(); } private async Task LoadDocumentsAsync() { Uri uri = new(NavigationManager.Uri); int dataSourceID = 0; switch (uri.Segments[1].ToLower()) { case "planter/": dataSourceID = 1068; break; case "kvaeg/": dataSourceID = 1067; break; case "maskiner/": dataSourceID = 1069; break; case "business/": dataSourceID = 1142; break; } DocumentFilter documentFilter = new() { DataSourceID = dataSourceID, WebSiteID = 16, ShowInFeed = true, ForceDataSourceUpdate = false }; ResponseDTO<IReadOnlyCollection<DocumentListDTO>> responseDTO = await DocumentCacheService.GetDocumentsAsync($"DataSource{dataSourceID}", documentFilter); // 更新组件绑定数据 } }
你之前觉得OnParametersSetAsync不适用,可能是没利用好路由切换的触发时机——只要组件是路由组件,每次导航到不同@page路径时,该方法都会被调用,完全可以替代原来的OnInitializedAsync逻辑。
方案3:重写SetParametersAsync方法
如果上述方案不符合需求,可以重写SetParametersAsync方法,每次组件接收参数(包括导航导致的路由参数变化)时执行数据加载逻辑。
示例代码:
public override async Task SetParametersAsync(ParameterView parameters) { await base.SetParametersAsync(parameters); await LoadDocumentsAsync(); } private async Task LoadDocumentsAsync() { // 和前面一致的数据加载逻辑 }
内容的提问来源于stack exchange,提问作者user2435866
相关产品推荐
相关产品推荐

