Bri*_*Kay 5 c# blazor blazor-server-side asp.net-core-3.1
我正在尝试在 Blazor 中实现面包屑。似乎没有任何机制可以将数据上游传递到布局级别,所以我想知道人们是如何管理它的。
这是我的布局的简化版本:
<header>
<Toolbar />
<Breadcrumbs></Breadcrumbs>
</header>
<main class="mt-5">
@Body
</main>
Run Code Online (Sandbox Code Playgroud)
这个想法是在任何给定的 Blazor 页面上,我希望能够设置面包屑。但是我的页面无法与布局或面包屑组件交互。
我考虑过/尝试过的事情:
在这个古老的 GitHub 问题中,Steve Sanderson 回应了类似的需求,但他的解决方法是侵入性的。我希望现在有更好的东西:https : //github.com/dotnet/aspnetcore/issues/16009
这很有趣,但最终没有帮助:Blazor:从布局访问参数
状态容器模式
我最终使用状态容器模式解决了这个问题。
如果您不知道那是什么,这些链接会很有帮助:
https://chrissainty.com/3-ways-to-communicate- Between-components-in-blazor/(最后一部分) https://www.youtube.com/watch?v=BB4lK2kfKf0&feature=youtu.be(深入探讨有附加选项)
概述
我做了一个 Scoped 服务只是为了处理导航。它被注入到我的导航栏组件中,用于管理面包屑。导航服务还有一个事件,只要面包屑发生变化,就会刷新导航栏 UI。
导航选项可以逐页配置。
为了让事情变得更容易,我还创建了一个继承自 ComponentBase 的基页。
我稍微简化了我的代码。在我的实际项目中,我管理的不仅仅是面包屑。
主布局
请注意标题中的导航栏组件。
<header>
<Navbar />
</header>
<main>
@Body
</main>
Run Code Online (Sandbox Code Playgroud)
导航栏组件
这使用 NavState 组件来构建我们的面包屑并处理可见性。此示例使用 mdbootstrap 4。在最后的代码块中,我们注册 OnChange 事件,并使用它来重新渲染组件。我们还实现 Dispose 来删除该事件绑定,否则可能会出现内存泄漏。
@inject NavState Nav
@implements IDisposable
<div class="subnav clearfix @(Nav.Visible ? "" : "invisible")">
@*BREADCRUMBS*@
<div class="float-left">
<ol class="breadcrumb">
@foreach (var item in Nav.Breadcrumbs)
{
if (item.Active)
{
<li class="breadcrumb-item active">@item.Text</li>
}
else
{
<li class="breadcrumb-item"><a href="@item.Link">@item.Text</a></li>
}
}
</ol>
</div>
</div>
@code {
protected override void OnInitialized()
{
Nav.OnChange += StateHasChanged;
}
public void Dispose()
{
Nav.OnChange -= StateHasChanged;
}
}
Run Code Online (Sandbox Code Playgroud)
导航状态服务
作为范围服务注入。在服务器端 Blazor 中,作用域服务在 Blazor 连接的生命周期内存在,因此我们必须小心在加载新页面时重置此服务。
另外值得注意的是:如果您打开多个选项卡,每个选项卡都有自己的连接,因此不会因一个用户打开多个选项卡而导致损坏。
public class NavState : IScopedService
{
public List<Breadcrumb> Breadcrumbs { get; set; } = new List<Breadcrumb>();
public bool Visible { get; set; } = false;
public event Action OnChange;
public void SetVisible(bool isVisible)
{
Visible = isVisible;
NotifyStateChanged();
}
public void Reset()
{
Breadcrumbs = new List<Breadcrumb>();
Visible = false;
NotifyStateChanged();
}
public void SetBreadcrumbs(List<Breadcrumb> breadcrumbs)
{
Breadcrumbs = breadcrumbs;
Visible = true;
NotifyStateChanged();
}
private void NotifyStateChanged() => OnChange?.Invoke();
}
}
Run Code Online (Sandbox Code Playgroud)
面包屑本身很简单:
public class Breadcrumb
{
public string Text { get; set; }
public string Link { get; set; }
public bool Active { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
基页
public class MyPageBase : ComponentBase
{
[Inject] protected NavState Nav { get; set; }
protected override void OnInitialized()
{
// NavState (breadcrumbs, etc) is Scoped, so it lives as long as our connection lives.
// So when a new page is visited, we need to clear navigation to prevent breadcrumbs from bleed-over, etc.
// This also makes the navbar invisible by default.
Nav.Reset();
}
}
Run Code Online (Sandbox Code Playgroud)
页数
有了这些,在您的页面上,如果您什么都不做,导航栏将是不可见的。或者您可以添加面包屑:
protected override async Task OnInitializedAsync()
{
...
Nav.SetBreadcrumbs(new List<Breadcrumb>()
{ new Breadcrumb(Text: "Test", Link: "https://google.com" }
);
...
}
Run Code Online (Sandbox Code Playgroud)
在我的实际实现中,我还创建了一个流畅的构建器,以使面包屑的使用不再那么笨重,但我不想让人们不知所措。
归档时间: |
|
查看次数: |
606 次 |
最近记录: |