深入浅出Blazor webassembly之使用EventCallback机制进行组件之间联动
===============================
总体思路
===============================
设想一个购物车的场景,对于购物车中的某个商品, 如果增加数量, 购物车总数量也要同步增加.
使用CascadingValue组件就无法实现这个要求, CascadingValue组件只能实现从上层组件传值到下层组件, 反向传值是不行的. EventCallback 因为有更高的灵活性, 能实现这样的功能,
总体思路:
⒈ 在事件源组件中定义一个 EventCallback<> 委托属性, 并将这个属性加上 Parameter 注解. 这是事件埋点, 关注该事件的其他组件必须注入一个Callback委托.
需要说明的是Blazor的 EventCallback<> 是单播 single cast 事件, 而 .Net 事件是多播.
代码示例: [Parameter] public EventCallback<MouseEventArgs> OnNumberAdded{ get; set;}
2. 在事件源组件的Trigger点, 进行委托调用
代码示例: await OnNumberAdded.InvokeAsync(e)
3. 在事件订阅方组件中, 为事件源组件注入一个埋点事件委托.
代码示例: <ProductItemUI ProductItem="product" OnNumberAdded="OnNumberAddedHandler"/>
===============================
完整示例:
===============================
ProductItem Data对象代码
//=========================== // file: Data\ProductItem.cs //=========================== namespace blazorDemo1.Data { public class ProductItem { public string Title{get ;set ;} public int Quantity{get ;set ;} } }
ProductItemUI 组件代码, 在组件中增加埋点Parameter, 并触发埋点委托
@* //================================ *@ @* // file: Shared\ProductItemUI.razor *@ @* //================================= *@ @using blazorDemo1.Data <tr> <td>@ProductItem.Title</td> <td>@ProductItem.Quantity</td> <td> <button type="button" class="btn btn-success btn-sm" @onclick="AddNumber">Add 1</button> </td> </tr> @code{ [Parameter] public ProductItem ProductItem {get ;set ;} [Parameter] public EventCallback<MouseEventArgs> OnNumberAdded{get ;set ;} public async Task AddNumber(MouseEventArgs e){ ProductItem.Quantity+=1 ; await OnNumberAdded.InvokeAsync(e) ; //在加1完成后, 触发埋点事件 } }
Cart 购物车组件, 注入埋点委托
@* //================================ *@ @* // file: Pages\Cart.razor *@ @* //================================= *@ @page "/cart" @using blazorDemo1.Data <div class="row"> <div class="col"> <h3>Buy Item List</h3> </div> <div class="col"> <h5 class="float-right"> Total Qty:@TotalQuantity</h5> </div> </div> <br> <table class="table"> <tr> <th>Title</th> <th> Qty</th> <th></th> </tr> @foreach (var Product in Products) { <ProductItemUI ProductItem="@Product" OnNumberAdded="@OnNumberAddedHandler"></ProductItemUI> } </table> @code { public List<ProductItem> Products; public int TotalQuantity; protected override void OnInitialized() { Products = new List<ProductItem>(){ new ProductItem(){Title="A", Quantity=10}, new ProductItem(){Title="B", Quantity=20}, new ProductItem(){Title="C", Quantity=30} }; UpdateTotalQty(); } void UpdateTotalQty() { TotalQuantity = Products.Sum(i => i.Quantity); } void OnNumberAddedHandler(MouseEventArgs e) { TotalQuantity = Products.Sum(i => i.Quantity); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2016-09-01 HTTP Basic Authentication