繁体   English   中英

如何从代码更新 Blazor static 布局

[英]How to update Blazor static layout from code

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

        <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>

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

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

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

我不确定您的 MainLayout 的布局,所以让我们假设 AuthorizeView 组件嵌入在 NavMenu 组件中,该组件本身嵌入在 MainLayout 组件中......

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

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

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

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();
}

这个 class 定义了一个名为 OnChange 的事件委托,它应该封装刷新 NavMenu 的方法。 当 boolean 属性 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;
}

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

启动 class

services.AddSingleton<AppState>();

如果生成事件的 class 是 static,则不需要 DI。 一个例子。 假设您想在 NavMenu 中交换组件的语言。 在根目录下创建 class AppStatus

public static class AppStatus
{
    public static event Action OnChange;
    // sample
    public static string Culture { get; set; } = "en-US";

    public static void UpdateLanguage() => NotifyStateChanged();

    static void NotifyStateChanged() => OnChange?.Invoke();
}

导航菜单.razor:

<div class="top-row pl-4 navbar navbar-dark">
    <a class="navbar-brand" href="">Blazor Multilanguage @AppStatus.Culture</a>
    <button class="navbar-toggler" @onclick="ToggleNavMenu">
        <span class="navbar-toggler-icon"></span>
    </button>
</div>
// ...
// add item
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="set-lang">
                <span class="oi oi-list-rich" aria-hidden="true"></span> Set Language
            </NavLink>
        </li>
    </ul>
</div>

@code {
    private bool collapseNavMenu = true;
    private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
    private void ToggleNavMenu() => collapseNavMenu = !collapseNavMenu;
    // subscribe event 
    protected override void OnInitialized() => AppStatus.OnChange += StateHasChanged;
    public void Dispose() => AppStatus.OnChange -= StateHasChanged;
}

创建组件SetLanguage.razor:

@page "/set-lang"
<h3>SetLanguage</h3>
<button class="btn btn-primary" @onclick="ChangeLanguage">Toggle Language</button>

@code {
    void ChangeLanguage()
    {
        AppStatus.Culture = AppStatus.Culture == "en-US" ? "ru-RU": "en-US";
        AppStatus.UpdateLanguage();
    }
}

单击按钮时,NavMenu 会更新 state... 我只说明了解决所咨询问题的部分

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM