Blazor Web应用程序加载时,页脚首先显示 [英] Footer showing first when Blazor web application loads

查看:52
本文介绍了Blazor Web应用程序加载时,页脚首先显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆