【问题标题】:Footer showing first when Blazor web application loads在 Blazor Web 应用程序加载时首先显示页脚
【发布时间】:2021-01-26 05:16:23
【问题描述】:

我有一个 Blazor .net 核心托管应用程序。当网站运行时,页脚会显示几秒钟,同时应用程序进行授权。有什么方法可以在运行某些活动时显示加载指示器?我特别指的是应用程序授权的时间。我希望在显示页脚之前加载内容?请看截图。

【问题讨论】:

    标签: asp.net-core blazor


    【解决方案1】:

    根据您的描述,如果我理解正确,“AppState”方法可能会很有用。这是一种在其层次结构中的任何级别启用组件之间通信的方法。

    让我们从定义AppState 开始。此类使用 .NET 事件在值发生更改时发出通知。

    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,它应该是一个作用域。

    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 组件使用此状态并订阅更改事件并更新本地字段。此字段用于确定是否显示页脚。作为一种好的做法,Footer 实现了IDisposable 以取消订阅事件。

    @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 正确处理它。

    在所有其他组件中,您可以注入AppState 并更改LoadingIsFinished 的值。假设你有一个 Dashboard 组件,你可以像这样使用 AppState。

    @inject AppState _appstate
    
    <h3>Dashboard</h3>
    
    @code {
    
        protected override void OnInitialized()
        {
            base.OnInitialized();
            _appstate.LoadingIsFinished = true;
        }
    }
    

    AppState 耦合到身份验证

    如果您的问题更多关于身份验证,可以使用专门的方法来解决。您可以将AuthenticationStateProvider 注入AppState,引入一个新属性,如IsAuthenticated,并在您的Footer 组件中使用此属性。

     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。

    【讨论】:

    • 感谢您非常详细和及时的回复!我决定切换到我有梦想之船体验的 Blazor 服务器。就个人而言,我不认为 MS 团队已经对 a.net core 托管 Wasm 的管道进行了排序。我在使用服务器时遇到零问题。我们真的不应该花这么多精力来管理应用程序中的简单页脚。独立的 .net 核心没有这些问题,所以这本质上是一个倒退。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    • 2022-01-16
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多