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