如何将值从页面传递到 Blazor 中的布局?
How to pass a value from a page to the layout in Blazor?
我有一个布局 (MainLayout.razor
),它有一个名为 ShowFooter
的标志。在某些页面上,我希望能够将该标志设置为 true
,将其他一些设置为 false
。
我无法找到关于页面(即具有路由的组件)如何与其布局通信的任何明确说明。 could/should 这在 Blazor 中如何完成?
注意:您可能建议使用 2 种布局,一种有页脚,一种没有页脚,但这并不能真正解决我的问题,我希望能够显示和在同一页的不同时间隐藏页脚。另外,这只是需要在布局和页面之间进行通信的一种情况。还有无数其他的。
您可以使用通知服务并将其注入组件。
public class NotifyService
{
public event Func<bool, Task> Notify;
public async Task Notify(bool value)
{
if (Notify is object)
{
await Notify.Invoke(value);
}
}
}
然后在 DI 容器中将其注册为单例(如果在服务器端则为范围)并将其注入到您的组件中。
有几种方法可以做到:
最丑陋的:如果你有两个模板,你可以简单地 select 你想使用的模板,在 page/component 的顶部使用以下内容:
@layout NoFooterLayoutName
在模板中使用级联值(我会为您的场景推荐什么):
<CascadingValue Value="Footer">
<Child />
</CascadingValue>
示例fiddle:
https://blazorfiddle.com/s/05spcuyk
- 创建一个 State 服务并将其添加到 startup as scoped。带有 footer bool 变量的状态服务,然后可以注入 pages/components 和使用的变量:
在startup.cs ConfigureService 方法中:
services.AddScoped<AppState>();
在项目的某处创建AppState.cs class(最好是服务文件夹):
public class AppState
{
public bool ShowFooter { get; set; }
public event Action StateChanged;
private void NotifyStateChanged() => StateChanged?.Invoke();
}
然后将其注入您的 page/components,以便您可以更改 ShowFooter 元素,并在您的模板中为触发 StateHasChanged() 创建事件处理程序(不确定是否需要):
@inject AppState _AppState;
@implements IDisposable
.
.
.
@code{
protected override void OnInitialized()
{
_appState.StateChanged += StateChanged;
}
public void StateChanged()
{
StateHasChanged();
}
public void Dispose()
{
_appState.StateChanged -= StateChanged;
}
}
最简单的方法是在 MainLaout 组件中定义一个名为 ShowFooter 的 public 布尔值 属性,如下所示:
public bool ShowFooter {get; set;}
并通过将标记包装在 Value 属性设置为 this
的 CascadingValue
组件中,将对 MainLaout 组件的引用级联到给定组件,如下所示:
@inherits LayoutComponentBase
<CascadingValue Value="this">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="content px-4">
@Body
</div>
</div>
</CascadingValue>
@code
{
public bool ShowFooter {get; set;}
protected override void OnInitialized()
{
// Put here code that checks the value of ShowFooter and acts in
// accordance with your dear wishes
}
}
在Index.razor
中的用法
@code{
// Gets a reference to the MainLayout component
[CascadingParameter]
public MainLayout Layout { get; set; }
protected override void OnInitialized()
{
Layout.ShowFooter= true;
}
}
我有一个布局 (MainLayout.razor
),它有一个名为 ShowFooter
的标志。在某些页面上,我希望能够将该标志设置为 true
,将其他一些设置为 false
。
我无法找到关于页面(即具有路由的组件)如何与其布局通信的任何明确说明。 could/should 这在 Blazor 中如何完成?
注意:您可能建议使用 2 种布局,一种有页脚,一种没有页脚,但这并不能真正解决我的问题,我希望能够显示和在同一页的不同时间隐藏页脚。另外,这只是需要在布局和页面之间进行通信的一种情况。还有无数其他的。
您可以使用通知服务并将其注入组件。
public class NotifyService
{
public event Func<bool, Task> Notify;
public async Task Notify(bool value)
{
if (Notify is object)
{
await Notify.Invoke(value);
}
}
}
然后在 DI 容器中将其注册为单例(如果在服务器端则为范围)并将其注入到您的组件中。
有几种方法可以做到:
最丑陋的:如果你有两个模板,你可以简单地 select 你想使用的模板,在 page/component 的顶部使用以下内容:
@layout NoFooterLayoutName
在模板中使用级联值(我会为您的场景推荐什么):
<CascadingValue Value="Footer"> <Child /> </CascadingValue>
示例fiddle: https://blazorfiddle.com/s/05spcuyk
- 创建一个 State 服务并将其添加到 startup as scoped。带有 footer bool 变量的状态服务,然后可以注入 pages/components 和使用的变量:
在startup.cs ConfigureService 方法中:
services.AddScoped<AppState>();
在项目的某处创建AppState.cs class(最好是服务文件夹):
public class AppState
{
public bool ShowFooter { get; set; }
public event Action StateChanged;
private void NotifyStateChanged() => StateChanged?.Invoke();
}
然后将其注入您的 page/components,以便您可以更改 ShowFooter 元素,并在您的模板中为触发 StateHasChanged() 创建事件处理程序(不确定是否需要):
@inject AppState _AppState;
@implements IDisposable
.
.
.
@code{
protected override void OnInitialized()
{
_appState.StateChanged += StateChanged;
}
public void StateChanged()
{
StateHasChanged();
}
public void Dispose()
{
_appState.StateChanged -= StateChanged;
}
}
最简单的方法是在 MainLaout 组件中定义一个名为 ShowFooter 的 public 布尔值 属性,如下所示:
public bool ShowFooter {get; set;}
并通过将标记包装在 Value 属性设置为 this
的 CascadingValue
组件中,将对 MainLaout 组件的引用级联到给定组件,如下所示:
@inherits LayoutComponentBase
<CascadingValue Value="this">
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="content px-4">
@Body
</div>
</div>
</CascadingValue>
@code
{
public bool ShowFooter {get; set;}
protected override void OnInitialized()
{
// Put here code that checks the value of ShowFooter and acts in
// accordance with your dear wishes
}
}
在Index.razor
中的用法@code{
// Gets a reference to the MainLayout component
[CascadingParameter]
public MainLayout Layout { get; set; }
protected override void OnInitialized()
{
Layout.ShowFooter= true;
}
}