Blazor应用优化:如何实现先加载页面再从数据库填充数据?
解决Blazor页面先加载框架再异步填充数据的问题
嘿,我完全懂你的担忧——同步加载数据会直接阻塞页面渲染,现在小数据集都要1-2秒,数据量上去了肯定更糟。咱们要实现的就是先渲染页面框架,后台异步拉取数据填充的效果,其实只要把同步数据操作改成异步非阻塞模式就行,我一步步给你讲怎么改:
第一步:把数据仓储改成异步模式
你的IRepository和Repository目前都是同步方法,这会导致组件初始化时一直等着数据返回,没法先渲染页面。咱们先把它改成异步版本:
修改IRepository接口
注意using语句要放在命名空间外面,接口方法改成异步返回Task<List<Employee>>(符合C#异步命名规范,后缀加Async):
using System; using System.Collections.Generic; using System.Threading.Tasks; namespace BlazorCompanyManager.Data { public interface IRepository { Task<List<Employee>> GetEmployeesAsync(); Task<Employee> GetEmployeeAsync(Guid id); Task<bool> UpdateEmployeeAsync(Employee employee); Task AddEmployeeAsync(Employee employee); Task DeleteEmployeeAsync(Guid id); } }
修改Repository实现类
利用EF Core的异步扩展方法(需要引用Microsoft.EntityFrameworkCore),把同步的ToList()改成异步的ToListAsync():
using Microsoft.EntityFrameworkCore; using System.Collections.Generic; using System.Threading.Tasks; namespace BlazorCompanyManager.Data { public class Repository : IRepository { protected readonly ApplicationDbContext dbContext; public Repository(ApplicationDbContext db) { this.dbContext = db; } public async Task<List<Employee>> GetEmployeesAsync() { // 异步查询,不会阻塞主线程 return await this.dbContext.EmployeeTable.ToListAsync(); } // 其他方法同理改成异步,比如GetEmployeeAsync: public async Task<Employee> GetEmployeeAsync(Guid id) { return await this.dbContext.EmployeeTable.FirstOrDefaultAsync(e => e.Id == id); } // Update、Add、Delete方法也按异步模式修改,这里就不一一列举了 } }
第二步:修改Blazor组件实现异步初始化
现在组件可以用OnInitializedAsync异步加载数据,同时初始化空列表和加载状态,让页面先渲染框架:
public class EmployeesBase : ComponentBase { [Inject] protected IRepository Repository { get; set; } // 先初始化空列表,避免渲染时出现null引用 protected List<BlazorCompanyManager.Data.Employee> employees = new(); // 增加加载状态,用来显示加载提示 protected bool isLoading = true; protected override async Task OnInitializedAsync() { // 异步获取数据,不会阻塞页面渲染 employees = await Repository.GetEmployeesAsync(); // 数据加载完成后更新状态 isLoading = false; // 不需要手动调用StateHasChanged,Blazor会自动处理状态变更触发重新渲染 } }
第三步:在Razor页面添加加载状态UI
最后在你的员工列表Razor文件里,先渲染页面框架(比如表格表头),加载时显示提示,数据到位后再展示内容:
<h3>员工列表</h3> @if (isLoading) { <p>正在加载数据...</p> <!-- 先显示加载提示,让用户知道页面在工作 --> } else { <table class="table"> <thead> <tr> <th>姓名</th> <th>部门</th> <!-- 其他表头列 --> </tr> </thead> <tbody> @foreach (var emp in employees) { <tr> <td>@emp.Name</td> <td>@emp.Department</td> <!-- 其他数据列 --> </tr> } </tbody> </table> }
为什么之前用OnInitializedAsync没成功?
大概率是因为你的仓储方法还是同步的——就算用了OnInitializedAsync,里面调用同步的GetEmployees()还是会阻塞线程,页面根本没法先渲染。现在改成全异步链路后,组件初始化时会立刻返回渲染页面框架,后台悄悄拉取数据,数据加载完成后自动更新UI,完美解决你的问题!
内容的提问来源于stack exchange,提问作者10101
相关产品推荐
相关产品推荐

