【问题标题】:Blazor - contextual buttons in parent component changed by child componentBlazor - 父组件中的上下文按钮由子组件更改
【发布时间】:2020-09-29 14:02:15
【问题描述】:

我希望有人能提供帮助,因为我是 Blazor 的新手。

我已经开始了一个新的 Blazor 项目,并尝试在顶部栏中添加上下文按钮,这些按钮可以通过 / 基于子组件进行更改(当您导航到第 1 页时,它可以显示与导航到时不同的内容第 2 页)

这是我目前的方法:

TopBar.razor - 带有渲染片段的顶栏模板,以便我可以渲染不同的东西

@inject Learning.Data.TopBarContext TopBarContext

<div class="col-sm-6">@Context</div>
<span class="col-sm-2">@Text1</span>
<span class="col-sm-2">@Text2</span>

@code {
    [Parameter]
    private RenderFragment Context { get; set; }

    [Parameter]
    public string Text1 { get; set; } = "Not Set";

    [Parameter]
    public string Text2 { get; set; } = "Not Set";    
}

MainLayout.razor - 我使用 TopBar 并将其级联到所有页面

@inherits LayoutComponentBase

<div class="sidebar">
    <NavMenu />
</div>

<div class="main">
    <div class="top-row px-4 auth">
        <TopBar />
    </div>

    <div class="content px-4">
        <CascadingValue Value="TopBar" Name="TopBar">
            @Body
        </CascadingValue>        
    </div>
</div>

@code {
    private TopBar TopBar;
}

现在我要两个页面组件:

Page1.razor - 导航到时会在顶部栏中呈现 3 个按钮

@page "/page1"

<button>One</button>
<button>Two</button>
<button>Three</button>

@code {

}

Page2.razor - 导航到时会在顶部栏中呈现 2 个按钮

@page "/page2"

<button>One</button>
<button>Two</button>

@code {

}

我知道我可以使用下面的代码来获取级联值:

[CascadingParameter(Name = "TopBar")]
    protected string TopBar { get; set; }

但不知道如何继续,我希望能够将整个组件向下级联,以便在 page1 中执行一些灵活的操作,例如:

<TopBar>
    <button>One</button>
    <button>Two</button>
    <button>Three</button>
</TopBar>

我可能会以完全错误的方式进行此操作(我确实认为创建注册单例可能是一种方法),但您可以就如何完成此操作提供任何说明,我们将不胜感激!

非常感谢

尼克

【问题讨论】:

    标签: data-binding blazor


    【解决方案1】:

    看看上面的内容,你就快到了。您可以将TopBar 级联起来,就像您在 MainLayout 中拥有它一样,但是您选择它的代码部分会让您失望。您将级联值显示为字符串属性,但请记住 Blazor 组件是已编译的 ,因此您需要将其列为类:

    [CascadingParameter]
    public TopBar Bar { get; set; }
    

    这就是你将如何在你的组件中捕获它,然后你可以访问公共属性和方法来更新它们,使用像Bar.Context = // render fragment of your choice这样的代码

    这可能会有点棘手,因为您提供给 Context 属性的内容可能会很痛苦,因此最好让您的 TopBar 组件根据以下数据结构自己呈现某些内容:相反,它成立。我之前用字典做过一些工作良好的链接,所以在你的TopBar 中你会有一个私有属性:

    private Dictionary<string, string> LinkBodiesAndRefs { get; set; } = new Dictionary<string, string>();
    

    这存储了链接文本作为键,目标 URL 作为每条记录的值, 然后渲染它们,如下所示:

    TopBar.razor

    @foreach (KeyValuePair<string, string> entry in LinkBodiesAndRefs)
    {
        <a href="@entry.Value">@entry.Key</a>
    }
    

    然后在TopBar的@code块中,我添加了几个与字典交互的方法:

    TopBar.razor(续)

    @code {
    
        private Dictionary<string, string> LinkBodiesAndRefs { get; set; } = new Dictionary<string, string>();
    
        public void AddLink(string linkBody, string linkDestination)
        {
            LinkBodiesAndRefs.Add(linkBody, linkDestination);
            StateHasChanged();
        }
    
        public void RemoveLink(string linkBody)
        {
            LinkBodiesAndRefs.Remove(linkBody);
            StateHasChanged();
        }
    
        public void Clear()
        {
            LinkBodiesAndRefs = new Dictionary<string, string>();
            StateHasChanged();
        }
    }
    

    然后在捕获级联TopBar 的组件中,只需使用方法与数据结构进行交互,如您所期望的那样,无论是列表还是字典或其他:

    Bar.AddLink("Products", "/products");
    
    Bar.RemoveLink("Products");
    

    如果对象列表需要进一步交互,同样的方法可以用于对象列表,这些对象甚至可以是 Razor 组件,并且您可以在 TopBar 中有一个 RenderFragment 列表,如果需要,可以将其渲染出来。关键是CascadingValue 可以提供一个类,然后您可以定义与之交互的类,并且您可以使用各种恶作剧来使很酷的事情发生。

    希望这会有所帮助,而且我目前没有我的 IDE,因此可能有一些我在上面的示例中遗漏的语法需要解决。如果是这种情况,请提前道歉。

    【讨论】:

      猜你喜欢
      • 2021-07-19
      • 2022-01-13
      • 2021-07-04
      • 2020-10-08
      • 1970-01-01
      • 2020-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多