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

Blazor API调用完成后如何从子组件触发主RAZOR页面刷新并控制加载状态

解决方案

步骤1:改造Scoped服务AppState,增加状态管理和通知能力

你需要在AppState中加入加载状态标志、结果存储属性,以及状态变化通知事件,让所有订阅该事件的组件可以自动感知状态更新:

public class AppState
{
    // 控制加载动画显示的布尔触发器
    public bool IsLoading { get; private set; }
    // 存储API返回的搜索结果,替换为你实际的数据集类型
    public List<SearchResultItem> SearchResults { get; private set; } = new();
    // 状态变化通知事件
    public event Action OnStateChanged;

    // 发起API请求前调用,开启加载状态
    public void StartLoading()
    {
        IsLoading = true;
        NotifyStateChanged();
    }

    // API返回数据后调用,更新结果并关闭加载状态
    public void UpdateSearchResults(List<SearchResultItem> results)
    {
        IsLoading = false;
        SearchResults = results ?? new();
        NotifyStateChanged();
    }

    private void NotifyStateChanged() => OnStateChanged?.Invoke();
}

步骤2:改造SearchResults.razor页面

首先补充注入和接口实现

@page "/searchresults"
@layout PageTopComponents
@inject AppState AppState
@inject NavigationManager NavigationManager
@inject 你的API服务类 SearchApiService
@implements IAsyncDisposable

修改渲染逻辑,直接通过AppState的状态判断展示内容

<MainContentComponent.razor>
    @if (AppState.IsLoading)
    {
        <!-- 你的加载动画代码 -->
    }
    else if (AppState.SearchResults.Any())
    {
        @foreach (var item in AppState.SearchResults)
        {
            <!-- 渲染单条搜索结果 -->
        }
    }
    else
    {
        <p>暂无匹配结果</p>
    }

    <ContinueSearch.razor></ContinueSearch.razor>
    <Paginator.razor @ref="PaginatorComponentReference">
        <ChildContent>
            <!-- 原有数据渲染逻辑 -->
        </ChildContent>
    </Paginator.razor>
</MainContentComponent.razor>

补充@code块的逻辑,监听地址变化和状态更新

@code {
    public Paginator PaginatorComponentReference;

    protected override async Task OnInitializedAsync()
    {
        // 订阅地址变化事件:相同路由跳转时Blazor默认复用组件,不会触发初始化生命周期,需要手动监听地址变化
        NavigationManager.LocationChanged += OnLocationChanged;
        // 订阅AppState的状态变化,状态更新时自动刷新页面
        AppState.OnStateChanged += StateHasChanged;
        // 首次加载时执行搜索
        await ExecuteSearchAsync();
    }

    private async void OnLocationChanged(object sender, LocationChangedEventArgs e)
    {
        // 地址变化(包括查询参数变化)时重新执行搜索
        await ExecuteSearchAsync();
    }

    private async Task ExecuteSearchAsync()
    {
        // 解析当前查询参数
        Uri uri = navigationManager.ToAbsoluteUri(System.Net.WebUtility.UrlDecode(navigationManager.Uri));
        Dictionary<string, StringValues> queryStrings = QueryHelpers.ParseQuery(uri.Query);
        
        // 从queryStrings中提取搜索词、过滤条件等参数,拼装成你的API请求参数
        var requestParams = new 你的API请求参数类();
        // 示例:requestParams.Keyword = queryStrings["keyword"];
        // 示例:requestParams.Filter1 = queryStrings["filter1"];

        // 触发加载状态,调用API获取数据
        AppState.StartLoading();
        var searchResult = await SearchApiService.你的搜索方法(requestParams);
        AppState.UpdateSearchResults(searchResult);
    }

    // 页面销毁时取消订阅,避免内存泄漏
    public async ValueTask DisposeAsync()
    {
        NavigationManager.LocationChanged -= OnLocationChanged;
        AppState.OnStateChanged -= StateHasChanged;
    }
}

步骤3:过滤器组件逻辑无需修改

你原有NavigationManager.NavigateTo(href)的逻辑可以完全保留,现在页面已经可以感知到地址变化,自动触发重新搜索和页面刷新。


说明

之前生命周期方法不生效的核心原因:Blazor对于相同路由的跳转,默认会复用已有的组件实例,不会重新触发OnInitialized等初始化生命周期方法,因此你写的刷新逻辑只有首次进入页面时会执行。

内容的提问来源于stack exchange,提问作者Brian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:57:02