深入淺出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); } }


浙公網安備 33010602011771號