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

Blazor Server中Navbar下拉框变更时如何自动更新页面内容?

问题分析与解决方案

你的核心问题在于:使用静态变量currentEf存储选中年份时,其他页面组件无法感知该变量的变化——Index组件仅在初始化时获取一次值,后续年份变更不会触发页面更新和EF查询重新执行。同时StateHasChanged()仅会刷新当前Navbar组件,无法通知其他组件。

以下是两种可行的解决方案:


方案一:依赖注入状态容器(推荐,适配中大型应用)

通过创建共享状态服务,实现跨组件的状态通知与同步,这是Blazor官方推荐的状态管理方式。

1. 创建状态服务类

public class YearSelectionState
{
    private int _selectedYear;

    public int SelectedYear
    {
        get => _selectedYear;
        set
        {
            if (_selectedYear != value)
            {
                _selectedYear = value;
                YearChanged?.Invoke(this, EventArgs.Empty);
            }
        }
    }

    // 年份变更事件,供其他组件订阅
    public event EventHandler? YearChanged;
}

2. 注册服务到Program.cs

builder.Services.AddScoped<YearSelectionState>();

3. 修改Navbar组件

@inject YearSelectionState YearState

<InputSelect class="form-select" @bind-Value="YearState.SelectedYear">
    <option value="2023">2023</option>
    <option value="2024">2024</option>
    <option value="2025">2025</option>
</InputSelect>

@code {
    private bool collapseNavMenu = true;
    private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }

    protected override void OnInitialized()
    {
        if (YearState.SelectedYear == 0)
        {
            YearState.SelectedYear = DateTime.Now.Year;
        }
    }
}

4. 修改Index组件(支持自动更新与EF查询)

@page "/"
@inject YearSelectionState YearState
@implements IDisposable

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<label>Year Selected: @YearSelected.ToString()</label>
<!-- 这里添加你的数据表格 -->

@code {
    int YearSelected;

    protected override void OnInitialized()
    {
        YearSelected = YearState.SelectedYear;
        // 订阅年份变更事件
        YearState.YearChanged += OnYearChanged;
        // 初始化加载数据
        LoadDataForSelectedYear();
    }

    private void OnYearChanged(object? sender, EventArgs e)
    {
        YearSelected = YearState.SelectedYear;
        // 重新执行EF查询加载对应年份的数据
        LoadDataForSelectedYear();
        StateHasChanged();
    }

    // 示例EF查询方法
    private void LoadDataForSelectedYear()
    {
        // 替换为你的实际EF查询逻辑
        // var data = _dbContext.YourEntities.Where(x => x.Year == YearSelected).ToList();
    }

    // 组件销毁时取消订阅,避免内存泄漏
    public void Dispose()
    {
        YearState.YearChanged -= OnYearChanged;
    }
}

方案二:事件回调+级联值(适合小型简单应用)

通过Navbar组件的事件回调通知父布局,再用级联值传递年份给子页面组件。

1. 修改Navbar组件

<InputSelect class="form-select" Value="efSel" ValueChanged="@((int value) => OnYearSelectedChanged(value))" ValueExpression="@(() => efSel)">
    <option value="2023">2023</option>
    <option value="2024">2024</option>
    <option value="2025">2025</option>
</InputSelect>

@code {
    [Parameter]
    public EventCallback<int> OnYearChanged { get; set; }

    private int efSel;

    private bool collapseNavMenu = true;
    private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;

    private void ToggleNavMenu()
    {
        collapseNavMenu = !collapseNavMenu;
    }

    protected override void OnInitialized()
    {
        efSel = DateTime.Now.Year;
    }

    private async Task OnYearSelectedChanged(int value)
    {
        efSel = value;
        await OnYearChanged.InvokeAsync(value);
    }
}

2. 修改MainLayout.razor

@inherits LayoutComponentBase

<div class="page">
    <div class="sidebar">
        <NavMenu OnYearChanged="HandleYearChanged" />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>

        <article class="content px-4">
            <!-- 用级联值传递选中年份给子页面 -->
            <CascadingValue Name="SelectedYear" Value="CurrentSelectedYear">
                @Body
            </CascadingValue>
        </article>
    </main>
</div>

@code {
    private int CurrentSelectedYear;

    private void HandleYearChanged(int year)
    {
        CurrentSelectedYear = year;
    }
}

3. 修改Index组件

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<label>Year Selected: @SelectedYear.ToString()</label>

@code {
    [CascadingParameter(Name = "SelectedYear")]
    public int SelectedYear { get; set; }

    // 每次年份参数变化时重新执行EF查询
    protected override void OnParametersSet()
    {
        LoadDataForYear(SelectedYear);
        base.OnParametersSet();
    }

    private void LoadDataForYear(int year)
    {
        // 替换为你的EF查询逻辑
    }
}

内容的提问来源于stack exchange,提问作者Luca C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 07:24:59