You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 04:55:27