围绕 StateHasChanged() 进行了很多精彩的讨论,但为了回答 OP 的问题,这里有另一种实现微调器的方法,通用,用于 HttpClient 调用后端 API。
此代码来自 Blazor Webassembly 应用程序...
Program.cs
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<SpinnerService>();
builder.Services.AddScoped<SpinnerHandler>();
builder.Services.AddScoped(s =>
{
SpinnerHandler spinHandler = s.GetRequiredService<SpinnerHandler>();
spinHandler.InnerHandler = new HttpClientHandler();
NavigationManager navManager = s.GetRequiredService<NavigationManager>();
return new HttpClient(spinHandler)
{
BaseAddress = new Uri(navManager.BaseUri)
};
});
await builder.Build().RunAsync();
}
SpinnerHandler.cs
注意:记得取消注释人工延迟。如果您在 Visual Studio 中使用开箱即用的 Webassembly 模板,请单击 天气预报 以查看运行中的微调器演示。
public class SpinnerHandler : DelegatingHandler
{
private readonly SpinnerService _spinnerService;
public SpinnerHandler(SpinnerService spinnerService)
{
_spinnerService = spinnerService;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
_spinnerService.Show();
//await Task.Delay(3000); // artificial delay for testing
var response = await base.SendAsync(request, cancellationToken);
_spinnerService.Hide();
return response;
}
}
SpinnerService.cs
public class SpinnerService
{
public event Action OnShow;
public event Action OnHide;
public void Show()
{
OnShow?.Invoke();
}
public void Hide()
{
OnHide?.Invoke();
}
}
MainLayout.razor
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
<a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
</div>
<div class="content px-4">
@Body
<Spinner />
</div>
</div>
</div>
Spinner.razor
注意:要添加一些变化,您可以在 OnIntialized() 方法中生成一个随机数,并在div 选择随机微调器类型。在此方法中,对于每个 HttpClient 请求,最终用户将观察到随机微调器类型。为简洁起见,此示例已被精简为仅一种类型的微调器。
@inject SpinnerService SpinnerService
@if (isVisible)
{
<div class="spinner-container">
<Spinner_Wave />
</div>
}
@code
{
protected bool isVisible { get; set; }
protected override void OnInitialized()
{
SpinnerService.OnShow += ShowSpinner;
SpinnerService.OnHide += HideSpinner;
}
public void ShowSpinner()
{
isVisible = true;
StateHasChanged();
}
public void HideSpinner()
{
isVisible = false;
StateHasChanged();
}
}
Spinner-Wave.razor
归功于:https://tobiasahlin.com/spinkit/
注意:这个旋转套件有一个 Nuget 包。 Nuget 包的缺点是您无法直接访问 CSS 进行调整。在这里,我调整了微调器的大小,并将背景颜色设置为与网站的原色相匹配,如果您在整个网站中使用 CSS 主题(或者可能是多个 CSS 主题),这将很有帮助
@* Credit: https://tobiasahlin.com/spinkit/ *@
<div class="spin-wave">
<div class="spin-rect spin-rect1"></div>
<div class="spin-rect spin-rect2"></div>
<div class="spin-rect spin-rect3"></div>
<div class="spin-rect spin-rect4"></div>
<div class="spin-rect spin-rect5"></div>
</div>
<div class="h3 text-center">
<strong>Loading...</strong>
</div>
<style>
.spin-wave {
margin: 10px auto;
width: 200px;
height: 160px;
text-align: center;
font-size: 10px;
}
.spin-wave .spin-rect {
background-color: var(--primary);
height: 100%;
width: 20px;
display: inline-block;
-webkit-animation: spin-waveStretchDelay 1.2s infinite ease-in-out;
animation: spin-waveStretchDelay 1.2s infinite ease-in-out;
}
.spin-wave .spin-rect1 {
-webkit-animation-delay: -1.2s;
animation-delay: -1.2s;
}
.spin-wave .spin-rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.spin-wave .spin-rect3 {
-webkit-animation-delay: -1s;
animation-delay: -1s;
}
.spin-wave .spin-rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.spin-wave .spin-rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
@@-webkit-keyframes spin-waveStretchDelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4);
transform: scaleY(0.4);
}
20% {
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
}
@@keyframes spin-waveStretchDelay {
0%, 40%, 100% {
-webkit-transform: scaleY(0.4);
transform: scaleY(0.4);
}
20% {
-webkit-transform: scaleY(1);
transform: scaleY(1);
}
}
</style>
很漂亮