我正在使用一个自定义基础组件类,每个自定义页面都继承自该基础类。
我没有任何剃须刀代码,因为它不会在我的基本组件类中进行模板化-仅应包含一些基本逻辑和初始化内容。
现在,我想包装一个级联值,因为在将嵌套在任何子级中的任何组件/页面上,都应该可以访问我的基类的属性值。我该怎么做,我试图在基本组件上伪造一些childContent,但是我没有工作
public class BaseComponent : ComponentBase
{
[Parameter] public RenderFragement ChildContent {get;set;}
protected override void OnInitialized()
{
ChildContent = b =>
{
b.OpenComponent<CascadingValue<IBvdDataComponent>>(0);
b.AddAttribute(1, "Name", "DataComponent");
b.AddAttribute(2, "Value", this);
b.CloseComponent();
};
}
}
My page component:
@page "/anypage"
@inherits BaseComponent
<div>
<MyNestedComponent />
</div>
我想在MyNestedComponent中做
[CascadingParameter]
public BaseComponent BaseComponent { get; set; }
什么是正确的方法?
答案 0 :(得分:1)
如果您乐于使用一些反射功能,则有可能。
public class MyBase : ComponentBase
{
string someValue = "test";
public MyBase()
{
var rf = typeof(ComponentBase).GetField("_renderFragment", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var pqr= typeof(ComponentBase).GetField("_hasPendingQueuedRender", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
var nr= typeof(ComponentBase).GetField("_hasNeverRendered", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
rf.SetValue(this, (RenderFragment)(builder =>
{
pqr.SetValue(this, false);
nr.SetValue(this, false);
builder.OpenComponent<CascadingValue<string>>(1);
builder.AddAttribute(2, "Value", someValue);
builder.AddAttribute(3, "ChildContent", (RenderFragment)( builder2 => BuildRenderTree(builder2)));
builder.CloseComponent();
}));
}
}
这将自动为所有子组件包括一个针对“ someValue”的CascadingValue。
如果您不想使用反射,则可以创建自己的基础组件来实现ComponentBase
所做的所有事情,然后以类似的方式修改构造函数,但直接引用字段而不使用反射。 / p>
答案 1 :(得分:0)
我遇到了类似的情况,我需要在 Base Component 类中创建一个 CascadingValue
,因为我想要对父级的引用并允许自定义 HTML 标签,我想知道如何实现这一点的唯一方法是手动构建组件树,但我没有在 Base 构造函数中使用 Reflection
,而是使用了 BuildRenderTree(RenderTreeBuilder builder)
方法。
public class Panel : ComponentBase
{
[CascadingParameter]
public Panel ParentPanel { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public string Tag { get; set; } = "div";
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
base.BuildRenderTree(builder);
// Add the panel element
builder.OpenElement(0, Tag);
// Add the CascadingValue component
builder.OpenComponent<CascadingValue<Panel>>(1);
builder.AddAttribute(2, "Value", this);
// Need to add the ChildContent attribute first then add the actual ChildContent component
// using a callback
builder.AddAttribute(3, "ChildContent", (RenderFragment)((builder2) => {
builder2.AddContent(4, ChildContent);
}));
builder.CloseComponent(); // Close the CascadingValue
builder.CloseElement(); // Close the Tag element
}
}