Изменить видимость навигационного элемента в меню Blazor - PullRequest
2 голосов
/ 07 января 2020

Я использую Blazor с. NET Core 3.0. Я хочу показать логин в моем меню, когда пользователь еще не вошел в систему. Когда он вошел в систему, то элемент навигации должен быть скрыт. Как я могу это сделать?

РЕДАКТИРОВАТЬ: я изменил метод OnInitializedAsyn c, используя asyn c Task, но это не проблема. Для первой загрузки все работает правильно. Но тогда я go на странице входа в систему, войдите в систему и перейдите на домашнюю страницу через 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";
    }

}

Ответы [ 4 ]

4 голосов
/ 08 января 2020

Я изменил свой код выше, но все еще не работает

Я думаю, я понимаю, что вы хотите ... Ниже приведен код для достижения этой цели, при условии, что я прав ... Вы хотите обновить sh содержимое компонента NavMenu, встроенного в компонент MainLayout, со страницы входа, верно?

Вы можете использовать различные методы для достижения этой цели. Следующее решение основано на шаблоне состояния приложения.

Прежде всего, мы должны создать класс обслуживания, к которому можно получить доступ как из компонента 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();
}

Этот класс определяет делегат события с именем OnChange, который должен инкапсулировать метод, который будет обновлять sh NavMenu. Этот делегат вызывается при изменении значения логического свойства LoggedIn. Значение свойства LoggedIn может измениться на странице входа в систему, когда пользователь вошел в систему, поэтому любой подписчик этого делегата, в нашем случае NavMenu, будет уведомлен об этом.

Страница входа

  • @inject AppState AppState Обратите внимание, что вышеизложенное вводит AppState на страницу входа. Поместите в верхнюю часть страницы

  • AppState.LoggedIn = true;, этот код должен быть указан в конце процедуры входа в систему. Это инициирует запуск делегата OnChange.

компонент NavMenu

  • @inject AppState AppState
  • @implements IDisposable

*

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

public void Dispose()
{
    AppState.OnChange -= StateHasChanged;
}

Теперь при каждом входе в систему служба AppState уведомляет компонент NavMenu о повторном рендеринге, чтобы ссылка для входа в систему не отображалась (не отображалась)

Класс стартапа

services.AddSingleton<AppState>();
2 голосов
/ 07 января 2020

У вас есть

protected override async void OnInitialized()

, чтобы сделать это

protected override async Task OnInitializedAsync()

Почти всегда избегайте async void. В этом случае ваше приложение может запустить logi c для обновления пользовательского интерфейса до завершения TokenExistAsyn c (). Версия void не предназначена для использования asyn c, названия являются ориентировочными.

Кроме того, Blazor имеет специальную поддержку hidden и аналогичных атрибутов включения / выключения. Вы можете использовать:

<li class="nav-item px-3" hidden="@hideLogin">

При обращенной логике c вам потребуется (), как в hidden=@(!showLogin)
и в вашем блоке кода:

bool hideLogin = false;

...

  // _loginVisibility = "hidden";
  hideLogin = true;
1 голос
/ 07 января 2020

Я немного изменил ваш код ... Используйте Task вместо void. Вместо этого попробуйте этот фрагмент кода:

@code{

private string _loginVisibility = "visible";

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

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

}

Если это изменение не работает, проверьте ваши CSS classes

Примечание. Я считаю, что использование строкового значения для скрытия или отображение элемента li неверно. Вам не нужно скрывать элемент li. Это не должно быть оказано вообще. Вы можете определить логическую переменную следующим образом:

public bool ShowLink {get; set;} = true;

Как видите, для свойства установлено значение по умолчанию true, и, таким образом, элемент li отображается:

 @if ( ShowLink )
 {
 <li class="nav-item px-3">
        <NavLink class="nav-link" href="login">
            <span class="oi oi-person" aria-hidden="true"></span> 
 Login
        </NavLink>
    </li>
 }

И в методе TokenExistAsyn c следует установить значение false, если этот метод возвращает «да». И, таким образом, элемент li не отображается.

0 голосов
/ 28 апреля 2020

Я думаю, я знаю, в чем проблема. Код выше в порядке и будет работать. Возможная проблема может быть на странице входа. В случае чего-то вроде navigationManager.NavigateTo ("/ client / home") код NavMenu не будет срабатывать. Для этого вы должны использовать второй параметр: navigationManager.NavigateTo ("/ client / home", true); Я надеюсь, что это поможет.

...