更改 blazor 菜单中导航项的可见性

eve*_*ert 7 c# asp.net-core blazor .net-core-3.0

我在 .NET Core 3.0 中使用 Blazor。当用户尚未登录时,我想在我的菜单中显示登录信息。当他登录时,应该隐藏登录导航项。我怎样才能做到这一点?

编辑:我通过使用异步任务更改了 OnInitializedAsync 方法,但这不是问题。对于第一次加载,它可以正常工作。但是然后我转到登录页面,登录并通过 NavigationManager 导航到主页,菜单不会“刷新”。我该如何解决这个问题?

以下代码不起作用...

<div>
    <ul class="nav flex-column">
        <li class="nav-item px-3">
            <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                <span class="oi oi-home" aria-hidden="true"></span> Home
            </NavLink>
        </li>
        @if (!_isLoggedIn)
        {
            <li class="nav-item px-3">
                <NavLink class="nav-link" href="login">
                    <span class="oi oi-person" aria-hidden="true"></span> <LocalizedString Key="NavMenuLogin" />
                </NavLink>
            </li>
            <li class="nav-item px-3">
                <NavLink class="nav-link" href="licenseedit">
                    <span class="oi oi-spreadsheet" aria-hidden="true"></span> <LocalizedString Key="NavMenuRegistration" />
                </NavLink>
            </li>
        }
    </ul>
</div>

@code{

    private bool _isLoggedIn;

    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();
        await TokenExistAsync();
    }

    private async Task TokenExistAsync()
    {
        var retVal = await Http.GetStringAsync("api/Login/ExistToken");
        _isLoggedIn = retVal == "yes";
    }

}
Run Code Online (Sandbox Code Playgroud)

Isa*_*aac 6

我更改了上面的代码,但仍然无法正常工作

我想我明白你想要什么......以下是实现这一点的代码,前提是我是对的......你想从登录刷新嵌入在 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 组件重新呈现,以便登录链接不可见(未呈现)

创业班

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

  • 我在我的网站上使用这个并且效果很好。我的网站针对多个不同的数据库提供相同的页面,用户执行更改数据库的操作。我需要导航菜单链接来反映当前选择的数据库。然而,我需要做一个小改变,那就是注册服务范围。作为单身用户,每个用户都将获得最后一个用户选择的任何网站。感觉最初提出的问题也应该是这种情况? (2认同)

Hen*_*man 5

你有

protected override async void OnInitialized()
Run Code Online (Sandbox Code Playgroud)

做到这一点

protected override async Task OnInitializedAsync()
Run Code Online (Sandbox Code Playgroud)

几乎总是回避async void。在这种情况下,您的应用程序可以在 TokenExistAsync() 完成之前运行逻辑来更新 UI。该void版本并不意味着异步使用,名称仅供参考。

此外,Blazor 对hidden类似的开/关属性有特殊支持。您可以使用:

<li class="nav-item px-3" hidden="@hideLogin">
Run Code Online (Sandbox Code Playgroud)

使用反向逻辑,您将需要()hidden=@(!showLogin)
代码块中和代码块中:

bool hideLogin = false;

...

  // _loginVisibility = "hidden";
  hideLogin = true;
Run Code Online (Sandbox Code Playgroud)