Blazor MainLayout 作为 CascadingParameter 始终为 null

问题描述 投票:0回答:2

所以...我正在开发 Blazor 服务器应用程序,但在理解级联参数如何工作以及为什么我的 MainLayout 始终返回 null 方面遇到了麻烦。

我这样做: MainLayout.razor:

<CascadingValue Value="this">
    <PageTitle>Global</PageTitle>
    <div id="wrapper">
        <SfToolbar CssClass="dockToolbar">
            <ToolbarEvents Clicked="@Toggle"></ToolbarEvents>
            <ToolbarItems>
                <ToolbarItem PrefixIcon="e-icons e-menu" TooltipText="Menu"></ToolbarItem>
                <ToolbarItem>
                    <Template>
                        <div class="e-folder">
                            <div class="e-folder-name">Global</div>
                        </div>
                    </Template>
                </ToolbarItem>
            </ToolbarItems>
        </SfToolbar>
        <div id="main-content container-fluid col-md-12" class="maincontent">
            <div>
                <div class="content">@Body</div>
            </div>
        </div>
    </div>

和行为页面

登录.razor:

@page "/sign-in"

<ComponentLibrary.Components.AuthPage backUrl="/"></ComponentLibrary.Components.AuthPage>

@code {
    [CascadingParameter]
    public MainLayout? Layout { get; set; }

    protected override void OnInitialized()
    {
        Layout.userModel = null;
        Layout.RefreshSideBar();
        base.OnInitialized();
    }

}

但是当我进入登录页面时,由于某种原因我的布局为空,有什么建议需要查看吗?

我尝试在其他页面中创建一个新的布局示例,但这完全不是我需要的

c# blazor blazor-server-side
2个回答
1
投票

是的,你们是对的。我刚刚注意到有 2 个 MainLayout 文件,我错过了那部分,抱歉。从项目中删除额外的布局可以解决问题


-1
投票

那么让我们尝试重现您的问题。

从标准 Blazor 服务器项目开始。

@inherits LayoutComponentBase

<PageTitle>SO74799583</PageTitle>
<CascadingValue Value=this>
    <div class="page">
        <div class="sidebar">
            <NavMenu />

        </div>

        <main>
            <div class="top-row px-4">
                <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
            </div>

            <article class="content px-4">
                @Body
            </article>
        </main>
    </div>
</CascadingValue>

@code {
    public string RenderTime = DateTime.Now.ToLongTimeString();

    protected override bool ShouldRender()
    {
        RenderTime = DateTime.Now.ToLongTimeString();
        return true;
    }
}

和索引:

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<div class="bg-dark text-white p-2 m-2">
    Main Component last rendered at: @(this.mainLayout?.RenderTime ?? "Not Rendered")
</div>

@code {
    [CascadingParameter] private MainLayout? mainLayout { get; set; }
}

有效:

mainLayout
不为空。所以你没有向我们展示一切。

但是,您不应该级联或传递对组件的引用。

  1. 您无法控制它的生命周期:渲染器可以控制。当它不再需要它时,它会“处置”它。
  2. 您永远不应该尝试从其他组件使用某些功能。

如果您想在组件之间进行通信,请创建一个状态类,并且:

  1. 将其注册为服务并使用它来引发和注册事件。
  2. 级联它。

这是一个简单的例子。

public class MyState
{
    public string LastUpdateTime { get; private set; } = "Not Set";

    public event EventHandler<string>? Updated;

    public void SetTime()
    {
        this.LastUpdateTime = DateTime.Now.ToLongTimeString();
        this.Updated?.Invoke(this, this.LastUpdateTime);
    }
}

布局:

@inherits LayoutComponentBase

<PageTitle>SO74799583</PageTitle>
    <CascadingValue Value=myState>
        <div class="page">
            <div class="sidebar">
                <NavMenu />
            </div>

            <main>
                <div class="top-row px-4">
                    <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
                </div>

                <article class="content px-4">
                    <div class="alert alert-info">@RenderTime</div>
                    @Body
                </article>
            </main>
        </div>
    </CascadingValue>

@code {
    public string RenderTime = DateTime.Now.ToLongTimeString();
    private MyState myState = new();

    protected override void OnInitialized()
        => myState.Updated += OnUpdated;

    private void OnUpdated(object? sender, string value)
        => StateHasChanged();

    public void Dispose()
        => myState.Updated -= OnUpdated;
}

和索引:

@page "/"

<PageTitle>Index</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<div class="p-2 m-2">
    <button class="btn btn-primary" @onclick=Update>Update Time</button>
</div>

@code {
    [CascadingParameter] private MyState? myState { get; set; }

    private Task Update()
    {
        myState?.SetTime();
        return Task.CompletedTask;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.