所以...我正在开发 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();
}
}
但是当我进入登录页面时,由于某种原因我的布局为空,有什么建议需要查看吗?
我尝试在其他页面中创建一个新的布局示例,但这完全不是我需要的
是的,你们是对的。我刚刚注意到有 2 个 MainLayout 文件,我错过了那部分,抱歉。从项目中删除额外的布局可以解决问题
那么让我们尝试重现您的问题。
从标准 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
不为空。所以你没有向我们展示一切。
但是,您不应该级联或传递对组件的引用。
如果您想在组件之间进行通信,请创建一个状态类,并且:
这是一个简单的例子。
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;
}
}