如何从代码更新 Blazor 静态布局

Art*_*War 2 c# authorization blazor

我有一个带有侧边栏的主布局,对于授权和非授权用户来说是不同的。我要更新的地方看起来像那样

        <AuthorizeView>
            <Authorized>
                // Personal information matches in this component (it's just one more div this some code in it)
                <UserInfo />
            </Authorized>
            <NotAuthorized>
                <div class="sidebar-unathorized">
                    <span>
                        To get all privileges, <a href="/register"><strong>register</strong></a> or <a href="/login"><strong>login</strong></a> please
                    </span>
                </div>
            </NotAuthorized>
        </AuthorizeView>
Run Code Online (Sandbox Code Playgroud)

用户通过授权后,我希望他看到他的个人信息,所以在我的登录方法中,我做了一些类似的事情

public async void HandleValidSubmit()
{
    ...
   ((CustomAuthenticationStateProvider)authenticationStateProvider).AuthenticateUser(authorizedUser);
   navigationManager.NavigateTo("/");
   //here I want to update the layout
    ...
    return;
}
Run Code Online (Sandbox Code Playgroud)

并在我的 CustomAuthenticationStateProvider 设置当前用户后 NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(user))); ,我希望这足以让所有基于授权的组件进行更新。但事实并非如此。我尝试了 StateHasChanged() 方法,但可以理解的是它不会像那样工作,因为它只是更新触发它的组件。但是,如果您在登录后手动重新加载页面,一切都会好起来的。任何想法如何从代码更新布局?

Isa*_*aac 6

我不确定你的 MainLayout 的布局,所以让我们假设这个答案的震动,AuthorizeView 组件嵌入在 NavMenu 组件中,它本身嵌入在 MainLayout 组件中......

您想从登录页面刷新嵌入在 MainLayout 组件中的 NavMenu 组件的内容,对吗?

您可以使用各种方法来实现这一点。以下解决方案基于 App State Pattern。

首先,我们必须创建一个可以从 NavMenu 组件和 Login 组件访问的服务类。这是课程:

public class AppState
{
private bool _loggedIn;
public event Action OnChange;
public bool LoggedIn
{
    get { return _loggedIn; }
    set {
        if (_loggedIn != value)
        {
            _loggedIn = value;
            NotifyStateChanged();
        }
    }
 }

 private void NotifyStateChanged() => OnChange?.Invoke();
}
Run Code Online (Sandbox Code Playgroud)

这个类定义了一个名为 OnChange 的事件委托,它应该封装将刷新 NavMenu 的方法。当布尔属性 LoggedIn 的值更改时,将调用此委托。LoggedIn 属性的值可能会在登录页面中更改,当用户已登录时,因此此委托的任何订阅者(在我们的示例中为 NavMenu)都将收到通知。

登录页面

  • @inject AppState AppState 注意上面将 AppState 注入到登录页面。把它放在页面的顶部

  • AppState.LoggedIn = true;该代码应放在登录过程的末尾。这将启动 OnChange 委托的触发。

导航菜单组件

  • @inject AppState AppState
  • @implements IDisposable

*

protected override void OnInitialized()
{
    AppState.OnChange += StateHasChanged;
}

public void Dispose()
{
    AppState.OnChange -= StateHasChanged;
}
Run Code Online (Sandbox Code Playgroud)

现在,无论何时登录,AppState 服务都会通知 NavMenu 组件重新渲染,以便渲染 AuthorizeView 中的 Authorized 内容。

创业班

services.AddSingleton<AppState>();
Run Code Online (Sandbox Code Playgroud)