Blazor中孙组件(GrandChild Component)如何调用父组件方法?
这事儿其实很简单,EventCallback完全可以跨多层组件传递,核心就是把父组件的回调层层往下传就行,给你一套具体实现步骤和代码示例:
解决方案:层层传递EventCallback
1. 父组件(ParentComponent)
先定义添加商品到订单的方法,然后把这个方法包装成EventCallback<Product>传递给子组件。假设你的商品模型是Product,包含Id、Name、Price这些字段:
@* ParentComponent.razor *@ <h3>订单页面</h3> <p>已选商品:@OrderProducts.Count 件</p> <ChildComponent OnAddToOrder="AddProductToOrder" /> @code { private List<Product> OrderProducts { get; set; } = new(); // 核心添加方法 private void AddProductToOrder(Product product) { if (!OrderProducts.Any(p => p.Id == product.Id)) { OrderProducts.Add(product); } // 这里可以加其他逻辑,比如更新订单金额、提示用户等 } }
2. 子组件(ChildComponent)
子组件需要接收父组件传来的EventCallback<Product>,然后在循环渲染孙组件时,把这个回调再传递给孙组件:
@* ChildComponent.razor *@ <div class="product-list"> @foreach (var product in Products) { @* 必须加@key,避免Blazor渲染时出现状态混乱 *@ <GrandChildComponent @key="product.Id" Product="product" OnAddToOrder="OnAddToOrder" /> } </div> @code { // 模拟商品数据源,实际可能从API或服务获取 private List<Product> Products { get; set; } = new() { new Product { Id = 1, Name = "商品A", Price = 99.9m }, new Product { Id = 2, Name = "商品B", Price = 199.9m }, new Product { Id = 3, Name = "商品C", Price = 49.9m } }; // 接收父组件传来的回调参数 [Parameter] public EventCallback<Product> OnAddToOrder { get; set; } }
3. 孙组件(GrandChildComponent)
孙组件接收商品实例和回调,点击按钮时触发回调,把当前商品传给父组件的方法:
@* GrandChildComponent.razor *@ <div class="product-card"> <h4>@Product.Name</h4> <p>价格:@Product.Price.ToString("C")</p> <button @onclick="() => OnAddToOrder.InvokeAsync(Product)" class="add-btn">加入订单</button> </div> @code { // 接收子组件传来的商品对象 [Parameter] public Product Product { get; set; } = default!; // 接收子组件传来的回调 [Parameter] public EventCallback<Product> OnAddToOrder { get; set; } }
关键细节提醒
EventCallback是Blazor专门为UI交互设计的委托封装,不仅能跨多层组件传递,还能自动触发组件的状态更新(比直接传普通Func更可靠)。- 循环渲染组件时一定要加
@key,否则Blazor可能无法正确识别每个组件的状态,导致点击按钮时触发错误的回调。 - 如果不需要传递商品参数,也可以用不带泛型的
EventCallback,调用时直接写OnAddToOrder.InvokeAsync()就行。
内容的提问来源于stack exchange,提问作者CmF
相关产品推荐
相关产品推荐

