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

Blazor WASM如何将FilterMenu按钮点击事件绑定到@Body内Index页面方法

解决方案

Blazor WebAssembly 中实现Layout组件与@Body内页面的跨组件通信,有两种常用且稳定的实现方式:


方案1:扩展现有级联参数(适合小型项目)

无需新增服务,基于你现有代码结构修改即可:

步骤1:修改 FilterMenu.razor

修正EventCallback参数类型,触发回调传递筛选对象:

<div class="filterMenu">
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <button class="btn-success" @onclick="ApplyFilters">Do Work</button>
         </li>
    </ul>
</div>

@code {
    // 泛型改为你的筛选对象类型
    [Parameter]
    public EventCallback<FilterObject> OnClick_ApplyFilters { get; set; }

    private async Task ApplyFilters()
    {
        var filters = new FilterObject() { SomeFilter = "SomeValue"};
        // 向上触发回调到MainLayout
        await OnClick_ApplyFilters.InvokeAsync(filters);
    }
}

步骤2:修改 MainLayout.razor

新增通知事件,更新级联值后触发订阅通知:

<div class="container-fluid">
    <div class="row">
        <div class="col-md-2">
            <FilterMenu OnClick_ApplyFilters="ApplyFilters"></FilterMenu>
        </div>
        <!-- 级联当前Layout实例供内部页面获取事件和筛选值 -->
        <CascadingValue Value="this">
            <div class="content px-4">
                @Body
            </div>
        </CascadingValue>
    </div>
</div>

@code {
    // 公开筛选值供页面读取
    public Filters filters { get; set; } = new();
    // 筛选更新通知事件
    public event Action OnFilterUpdated;

    private async Task ApplyFilters(FilterObject filterObj)
    {
        // 更新筛选值
        filters = new Filters { SomeFilter = filterObj.SomeFilter };
        // 触发所有订阅该事件的页面方法
        OnFilterUpdated?.Invoke();
    }
}

步骤3:修改 Index.razor

订阅Layout的筛选更新事件,页面销毁时取消订阅避免内存泄漏:

@page "/"
@implements IDisposable

<div class="mainContent">
    <!-- 原有页面结构保留 -->
</div>

@code {
    // 接收级联的Layout实例
    [CascadingParameter]
    public MainLayout Layout { get; set; }

    protected override void OnInitialized()
    {
        // 订阅筛选更新事件
        Layout.OnFilterUpdated += GetGridData;
    }

    public async void GetGridData()
    {
        await LoadSampleData(Layout.filters);
        await LoadSampleData2(Layout.filters);
        // 手动触发UI刷新
        StateHasChanged();
    }

    // 页面销毁时取消订阅
    public void Dispose()
    {
        Layout.OnFilterUpdated -= GetGridData;
    }

    // 原有LoadSampleData、LoadSampleData2方法保留
}

方案2:全局状态服务(适合中大型项目)

解耦性更强,支持多页面同时响应筛选变更:

步骤1:新建筛选状态服务

新增FilterService.cs类:

public class FilterService
{
    // 当前全局筛选值
    public Filters CurrentFilters { get; private set; } = new();
    // 筛选更新通知事件
    public event Action OnFilterChanged;

    /// <summary>
    /// 更新全局筛选值并触发通知
    /// </summary>
    public void UpdateFilters(Filters newFilters)
    {
        CurrentFilters = newFilters;
        OnFilterChanged?.Invoke();
    }
}

步骤2:注册服务到依赖注入容器

修改Program.cs:

// 其他注册逻辑保留
builder.Services.AddScoped<FilterService>();

步骤3:修改 FilterMenu.razor

直接注入服务触发筛选更新:

@inject FilterService FilterService

<div class="filterMenu">
    <!-- 原有结构保留 -->
</div>

@code {
    private async Task ApplyFilters()
    {
        var filters = new Filters() { SomeFilter = "SomeValue"};
        FilterService.UpdateFilters(filters);
    }
}

该方案下MainLayout无需再绑定FilterMenu的回调参数

步骤4:修改 Index.razor

注入服务订阅事件:

@page "/"
@implements IDisposable
@inject FilterService FilterService

<div class="mainContent">
    <!-- 原有页面结构保留 -->
</div>

@code {
    protected override void OnInitialized()
    {
        FilterService.OnFilterChanged += GetGridData;
    }

    public async void GetGridData()
    {
        await LoadSampleData(FilterService.CurrentFilters);
        await LoadSampleData2(FilterService.CurrentFilters);
        StateHasChanged();
    }

    public void Dispose()
    {
        FilterService.OnFilterChanged -= GetGridData;
    }

    // 原有LoadSampleData、LoadSampleData2方法保留
}

注意事项

两种方案都需要在页面实现IDisposable接口,销毁时取消事件订阅,否则会出现内存泄漏、方法重复触发的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 04:18:03