基本组件布局继承 blazor

ame*_*lon 3 blazor

假设我的大部分组件都有一个标题。我想创建一个具有标头变量的基本组件,并使所有其他组件从该组件继承并设置标头。所以我有

基础组件

@inherits LayoutComponentBase;

<h1>@header</h1>

@Body

@code {

    protected string header;
}
Run Code Online (Sandbox Code Playgroud)

成分

@inherits BaseComponent;

"internal component text"

@code {
  protected override void OnInitialized()
    {
         base.header = "Setting header for the parent"
    }
}
Run Code Online (Sandbox Code Playgroud)

这将编译并显示没有错误,但基本标题没有显示。就像基地中的任何东西都没有被渲染。我究竟做错了什么?

聚苯乙烯

我也尝试过@layout BaseComponent,甚至同时尝试了两个指令。

jkd*_*dba 18

扩展 @sw1337 答案,如果派生组件没有 markdown,您可以将其创建为常规 cs 文件而不是 razor 文件,并且它将按预期工作,而无需调用基本 BuildRenderTree 方法。有关更多详细信息,请参阅此github

简单的例子

基础组件 (MyAbstractComponent.razor)

<h1>@header</h1>

@code {
    protected string header;
}
Run Code Online (Sandbox Code Playgroud)

派生组件

public class MyDerivedComponent : MyAbstractComponent
{
    protected override void OnInitialized()
    {
         header = "set header from derived component";
    }
}
Run Code Online (Sandbox Code Playgroud)

参数示例

基础组件 (MyAbstractComponent.razor)

<h1>@Header</h1>

@code {
  [Parameter] public string Header { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

派生组件

public class MyDerivedComponent : MyAbstractComponent
{
    protected override void OnParametersSet()
    {
        // coalesce
        Header ??= "Default Header from derived Component"
    }
}
Run Code Online (Sandbox Code Playgroud)

用法 1 - 来自派生组件的默认标头

一些剃刀文件

<MyDerivedComponent></MyDerivedComponent>
Run Code Online (Sandbox Code Playgroud)

结果

<h1>Default Header from derived Component</h1>
Run Code Online (Sandbox Code Playgroud)

用法 2 - 来自派生消费者的指定标头

一些剃刀文件

<MyDerivedComponent Header="MyHeader"></MyDerivedComponent>
Run Code Online (Sandbox Code Playgroud)

结果

<h1>MyHeader</h1>
Run Code Online (Sandbox Code Playgroud)

RenderFragment参数示例

布拉佐小提琴

MyBaseComponent.razor

<h3>@Header</h3>

@if (ChildContent is not null)
{
    @ChildContent
}

@code {
    [Parameter] public string Header { get; set; }
    [Parameter] public RenderFragment ChildContent { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

MyDerivedComponent.cs

public class MyDerivedComponent : MyBaseComponent
{
    protected override void OnParametersSet()
    {
        // coalesce
        Header ??= "Derived Component Header";
        ChildContent ??= CreateDefaultChildContent();
    }
        
    private static RenderFragment CreateDefaultChildContent()
    {
        return builder =>
        {
            builder.OpenElement(0, "h4");
            builder.AddContent(1, "Derived Component default child content value");
            builder.CloseElement();
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

用法 MyRazorPage.razor

示例 1 消费者不传递任何参数。使用派生组件的默认值Header和来自派生组件的默认值。ChildContent

代码

<MyDerivedComponent/>
Run Code Online (Sandbox Code Playgroud)

输出

<h3>Derived Component Header</h3>
<h4>Derived Component default child content value</h4>
Run Code Online (Sandbox Code Playgroud)

示例二 Consumer传递Header参数,ChildContent使用派生组件的默认值。

代码

<MyDerivedComponent Header="Consumer Header"/>
Run Code Online (Sandbox Code Playgroud)

输出

<h3>Consumer Header</h3>
<h4>Derived Component default child content value</h4>
Run Code Online (Sandbox Code Playgroud)

示例三 消费者传递HeaderChildContent参数。

代码

<MyDerivedComponent Header="Consumer Header">
    <h4>Child Content - from consumer</h4> 
</MyDerivedComponent>
Run Code Online (Sandbox Code Playgroud)

输出

<h3>Consumer Header</h3>
<h4>Child Content - from consumer</h4>
Run Code Online (Sandbox Code Playgroud)


sw1*_*337 6

在撰写本文时,派生的 razor 组件自动实现其基类的所有方法,包括 BuildRenderTree(呈现您在 razor 文件中键入的 HTML 标记)。当您不输入任何内容时,该方法将不会尝试自行调用基础 BuildRenderTree 方法。所以你需要像这样手动完成:

@inherits BaseComponent;

@{
    base.BuildRenderTree(__builder);
}

@code {
  protected override void OnInitialized()
    {
         base.header = "Setting header for the parent"
    }
}
Run Code Online (Sandbox Code Playgroud)

  • __builder 从哪里来? (4认同)
  • Stack Overflow 上不鼓励仅提供代码答案,因为它们没有解释它如何解决问题。请编辑您的答案,以解释此代码如何回答问题以及如何改进现有问题,以便它对 OP 以及具有类似问题的其他用户有用。 (2认同)
  • @FluffyKitten 你说得完全正确,当时是凌晨 2 点,我的脑子都炸了。我添加了一些细节! (2认同)

Ste*_*e W 3

2022 更新 - 这种方法在 .NET 6 中对我来说效果很好。

基础组件:

<h1>@Header</h1>

@code{
    public string? Header {get; set;}
}
Run Code Online (Sandbox Code Playgroud)

派生组件:

@inherits BaseComponent

@code {
    protected override void OnParametersSet()
    {
        base.Header = "New Header Value";
    }
}
Run Code Online (Sandbox Code Playgroud)