basic component layout inheritance blazor

﹥>﹥吖頭↗ 提交于 2021-01-29 19:47:40

问题


Let's say most of my components have a header. I want to create a base component that has the header variable and make all the other components inherit from that component and set the header. So I have

BaseComponent

@inherits LayoutComponentBase;

<h1>@header</h1>

@Body

@code {

    protected string header;
}

Component

@inherits BaseComponent;

"internal component text"

@code {
  protected override void OnInitialized()
    {
         base.header = "Setting header for the parent"
    }
}

This compiles and shows up with no errors but the base header doesn't show up. It's like anything in the base doesn't get rendered. What am I doing wrong?

P.S.

I have also tried @layout BaseComponent, and even both directives at the same time.


回答1:


As of this writing, derived razor components implement all methods of their base classes automatically, including BuildRenderTree (which renders the HTML markup that you type within the razor file). When you type nothing, that method will make no attempt at calling the base BuildRenderTree method on its own. So you need to do it manually like so:

@inherits BaseComponent;

@{
    base.BuildRenderTree(__builder);
}

@code {
  protected override void OnInitialized()
    {
         base.header = "Setting header for the parent"
    }
}



回答2:


It will never work in the way you're showing because setting a property on a parent component from an inner one doesn't trigger the rendering. AFAIK the right approach to this problem is to have an independent service class that holds some common state (in your case, the current page title), and inject it on every component that needs to change it, by meaning of event actions:

That would be something like this:

public class GlobalUtilities
{
    public string MainPageTitle { get; private set; } = "Home (default value)";

    public event Action OnMainTitleChanged;

    public void SetMainTitle(string text)
    {
        MainPageTitle = text;
        OnMainTitleChanged.Invoke();
    }
}

Register it on the pipeline in Startup.cs:

services.AddScoped<UtilsGlobales>();

it should be registered as scoped, since it's lifetime is paired with the current connection.

And then use it on all the descendant components you need:

Component

//No need to inherit, only inject...
// @inherits BaseComponent;

@inject GlobalUtilities gu

<p>Something here</p>

@code {
    protected void OnInitialized()
    {
        gu.SetMainTitle("Whatever you want");
    }
}

Hope it helps!



来源:https://stackoverflow.com/questions/59990832/basic-component-layout-inheritance-blazor

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!