【发布时间】:2021-01-26 05:16:23
【问题描述】:
我有一个 Blazor .net 核心托管应用程序。当网站运行时,页脚会显示几秒钟,同时应用程序进行授权。有什么方法可以在运行某些活动时显示加载指示器?我特别指的是应用程序授权的时间。我希望在显示页脚之前加载内容?请看截图。
【问题讨论】:
标签: asp.net-core blazor
我有一个 Blazor .net 核心托管应用程序。当网站运行时,页脚会显示几秒钟,同时应用程序进行授权。有什么方法可以在运行某些活动时显示加载指示器?我特别指的是应用程序授权的时间。我希望在显示页脚之前加载内容?请看截图。
【问题讨论】:
标签: asp.net-core blazor
根据您的描述,如果我理解正确,“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。
【讨论】: