Blazor Web应用程序加载时,页脚首先显示 [英] Footer showing first when Blazor web application loads
问题描述
我有一个Blazor .net核心托管应用程序.当网站运行时,在应用程序进行授权时,页脚会显示几秒钟.每当有一些活动在运行时,是否有任何方法可以显示负载指示器?我专门指的是应用授权的时间.我要在显示页脚之前加载内容吗?请查看屏幕截图.
I have a Blazor .net core hosted application. When the site runs, the footer shows for a few seconds while the app does authorizing. Is there any way to show a loading indicator whenever there is some activity running? I am specifically referring to when the app is authorizing. I want the contents to load before showing the footer? Please see screenshot.
推荐答案
根据您的描述,"AppState"如果我理解正确的话,这种方法可能会很有用.这是在组件层次结构中任何级别的组件之间启用通信的一种方法.
Based on your description, an "AppState" approach could be useful if I understood it correctly. It's a way to enable communication between components at any level in their hierarchy.
让我们从定义 AppState
开始.值更改后,此类使用.NET事件引发通知.
Let's start by defining the AppState
. This class uses the .NET events to raise a notification when a value has changed.
public class AppState
{
private Boolean _loadingIsFinished = false;
public Boolean LoadingIsFinished
{
get => _loadingIsFinished;
set
{
_loadingIsFinished = value;
AppStateChanged?.Invoke(this, EventArgs.Empty);
}
}
public event EventHandler AppStateChanged;
}
AppState已添加到依赖项注入系统.对于Blazor WASM,它应该是单例依赖项.但是,对于Blazor Server,它应该是作用域内的.
The AppState is added to the dependency injection system. For Blazor WASM, it should be a singleton dependency. For Blazor Server, though, it should be a scoped one.
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
...
builder.Services.AddSingleton(new AppState());
...
await builder.Build().RunAsync();
}
Footer
组件使用此状态并订阅change事件并更新本地字段.此字段用于确定是否显示页脚.作为一种好习惯, Footer
实施 IDisposable
取消订阅该事件.
The Footer
component uses this state and subscribe to the change event and update a local field. This field is used to determine if the footer is displayed or not. As a good practice, the Footer
implements the IDisposable
to unsubscribe from the event.
@inject AppState _appState
@implements IDisposable
@if (_showFooter == true)
{
<div class="footer">
@*Footer Content*@
</div>
}
@code {
private Boolean _showFooter = false;
protected override void OnInitialized()
{
base.OnInitialized();
_appState.AppStateChanged += AppStateChanged;
_showFooter = _appState.LoadingIsFinished;
}
private async void AppStateChanged(object sender, EventArgs args)
{
_showFooter = _appState.LoadingIsFinished;
await InvokeAsync(StateHasChanged);
}
public void Dispose()
{
_appState.AppStateChanged -= AppStateChanged;
}
}
由于AppState的更新可能会带外发生,因此我们通过调用 StateHasChanged
来强制UI更新.此外,该调用被包装在 InvokeAsync
中,以确保由UI正确处理.
Because the update of the AppState can happen out of band, we force the UI to update by calling StateHasChanged
. Besides, the call is wrapped inside InvokeAsync
to make sure it is handled correctly by the UI.
在每个其他组件中,您可以注入 AppState
并更改 LoadingIsFinished
的值.假设您有一个 Dashboard
组件,则可以像这样使用AppState.
In every other component, you can inject the AppState
and change the value of LoadingIsFinished
. Assuming you have a Dashboard
component, you could use the AppState like this.
@inject AppState _appstate
<h3>Dashboard</h3>
@code {
protected override void OnInitialized()
{
base.OnInitialized();
_appstate.LoadingIsFinished = true;
}
}
AppState结合身份验证
如果您的问题更多是关于身份验证,则有一种专门的方法来进行身份验证.您可以将 AuthenticationStateProvider
注入到 AppState
中,引入一个新属性,例如 IsAuthenticated
,并在 Footer
组件中使用此属性.
If your question is more about authentication, there is a specialized way to do it. You can inject AuthenticationStateProvider
into the AppState
, introduce a new property like IsAuthenticated
and use this property in your Footer
component.
public AppState(AuthenticationStateProvider authStateProvider)
{
_authStateProvider = authStateProvider;
_authStateProvider.AuthenticationStateChanged += HandleAuthStateChanged;
}
private async void HandleAuthStateChanged(Task<AuthenticationState> task)
{
var state = await task;
IsAuthentication = state.User != null && state.User.Claims.Any();
}
public void Dispose()
{
_authStateProvider.AuthenticationStateChanged -= HandleAuthStateChanged;
}
public event EventHandler AppStateChanged;
private Boolean _isAuthenticated = false;
public Boolean IsAuthenticated
{
get => _isAuthenticated;
set
{
_isAuthenticated = value;
AppStateChanged?.Invoke(this, EventArgs.Empty);
}
}
这是"AppState"的基本版本.但是,对于所有这些状态转换,都有类似 Fluxor 之类的框架,或者您可以使用更解耦的方式,例如用于组件的消息总线,称为 ComponentBus .
This is a fundamental version of an "AppState". However, there are frameworks like Fluxor for all these state transitions, or you could use a more decoupled way like a message bus for components, called ComponentBus.
这篇关于Blazor Web应用程序加载时,页脚首先显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!