Blazor父组件获取子组件属性方法及取值为0问题咨询
问题根因
- Blazor父子组件的生命周期触发顺序为:父组件首渲染完成触发
OnAfterRenderAsync(firstRender=true)时,子组件OnAfterRenderAsync内的异步数据库查询await db.Item.ToListAsync()还未执行完毕,count字段仍为默认初始值0,因此父组件此时调用子组件Count()方法只能拿到0 - 子组件异步查询结束更新
count值后,没有对应的通知机制触发父组件状态更新,因此父组件的ItemCount不会同步最新值
修复方案
方案1:使用EventCallback实现状态同步(推荐,符合Blazor单向数据流规范)
无需使用@ref获取子组件实例,通过回调参数实现子组件向父组件传值:
子组件代码调整
// 新增回调参数,用于向父组件传递count更新事件 [Parameter] public EventCallback<int> OnCountChanged { get; set; } private int count; protected override async Task OnAfterRenderAsync(bool firstRender) { if(firstRender) { Items = await db.Item.ToListAsync(); count = Items.Count; // count更新后主动通知父组件 await OnCountChanged.InvokeAsync(count); StateHasChanged(); } } public int Count() { return count; }
父组件代码调整
<Heading Size="HeadingSize.Is4">Count @ItemCount Entries</Heading> <!-- 绑定子组件的count更新回调,无需声明ref --> <StockComponent OnCountChanged="UpdateItemCount" /> @code { int ItemCount; private void UpdateItemCount(int newCount) { ItemCount = newCount; } }
方案2:保留@ref调用子组件方法的兼容写法
如果业务逻辑必须通过子组件实例获取值,可以将子组件的异步加载任务暴露给父组件等待:
子组件代码调整
// 对外暴露加载完成的任务,供父组件等待 public Task LoadCompleted { get; private set; } private int count; protected override async Task OnAfterRenderAsync(bool firstRender) { if(firstRender) { LoadCompleted = LoadItems(); await LoadCompleted; } } private async Task LoadItems() { Items = await db.Item.ToListAsync(); count = Items.Count; StateHasChanged(); } public int Count() { return count; }
父组件代码调整
<Heading Size="HeadingSize.Is4">Count @ItemCount Entries</Heading> <StockComponent @ref=stockComponent /> @code { StockComponent stockComponent; int ItemCount; protected override async Task OnAfterRenderAsync(bool firstRender) { if(firstRender) { // 等待子组件加载完成后再取值 await stockComponent.LoadCompleted; ItemCount = stockComponent.Count(); StateHasChanged(); } } }
内容的提问来源于stack exchange,提问作者รัฐพล.James
相关产品推荐
相关产品推荐

