上下文:我们有一个Blazor应用程序,包含以下3个文件:
- ChildComponent.razor
- ParentComponent.razor
- Test.razor(这是使用者,它使用父组件)
ChildComponent.rarzor
<div>
@if(Body != null)
{
@Body
}
@if(Footer != null)
{
<div class="footer">
@Footer
</div>
}
</div>
@code
{
[Parameter]
public RenderFragment Body { get; set; }
[Parameter]
public RenderFragment Footer { get; set; }
}
ParentComponent.rarzor
ParentComponent使用ChildComponent。我们希望将ParentFooter
传递给子组件的Footer
:
<ChildComponent Footer="ParentFooter">
<Body>
<p>@Text</p>
</Body>
</ChildComponent>
@code
{
[Parameter]
public string Text { get; set; }
[Parameter]
public RenderFragment ParentFooter { get; set; }
}
消耗文件是Test.rarzor,看起来像这样:
<ParentComponent Text="Hello World"></ParentComponent>
我们在这里不使用<ParentFooter></ParentFooter>
,因为页脚是可选的。
问题:
我们在浏览器控制台中得到一个异常:
未处理的异常呈现组件:委派到实例方法不能有null的"this"(参数"this")
可能的解决方案:
在ParentComponent.rarzor文件中,我们通过引用传递页脚,并进行null
-检查:
<ChildComponent Footer="ParentFooter" @ref="m_ChildComponentRef">
<Body>
<p>@Text</p>
</Body>
</ChildComponent>
@code
{
[Parameter]
public string Text { get; set; }
[Parameter]
public RenderFragment ParentFooter { get; set; }
private ChildComponent m_ChildComponentRef { get; set; }
protected override void OnParametersSet()
{
base.OnParametersSet();
if (ParentFooter != null)
{
m_ChildComponentRef.Footer = ParentFooter;
}
}
}
但这是一种糟糕的方式,因为我们收到了一个警告:
BL0005:组件参数不应设置在其组件之外。
问题:如何将可选的RenderFragment传递给子组件?
您是否尝试在子组件中将参数设置为默认值所以它看起来像这个
<div>
@if(Body != null)
{
@Body
}
@if(Footer != null)
{
@Footer
}
@code
{
[Parameter]
public RenderFragment Body { get; set; } = null;
[Parameter]
public RenderFragment Footer { get; set; } = null;
}
在父组件中,您还设置了默认值
@if(ParentFooter != null)
{
<ChildComponent Footer="ParentFooter">
<Body>
<p>@Text</p>
</Body>
</ChildComponent>
}
else {
// show something else
}
@code
{
[Parameter]
public string Text { get; set; }
[Parameter]
public RenderFragment ParentFooter { get; set; } = null;
}
如果这没有帮助,你能发布github链接吗
问候,
使用CascadingValue
作品:
ParentComponent.rarzor:
<CascadingValue Value="this">
<ChildComponent>
<Body>
<p>@Text</p>
</Body>
</ChildComponent>
</CascadingValue>
@code
{
[Parameter]
public string Text { get; set; }
[Parameter]
public RenderFragment ParentFooter { get; set; }
}
ChildComponent.rarzor:
<div>
@if (Body != null)
{
@Body
}
@if (ParentComponent != null && ParentComponent.ParentFooter != null)
{
<div class="footer">
@ParentComponent.ParentFooter
</div>
}
</div>
@code
{
[CascadingParameter]
public ParentComponent ParentComponent { get; set; }
[Parameter]
public RenderFragment Body { get; set; }
}
测试。剃刀:
<ParentComponent Text="Hello World">
@* <ParentFooter>Footer</ParentFooter> // <- Optional *@
</ParentComponent>
我认为如果你想用RenderFragment
构建你的页脚,它会很容易传递。
父组件
<ChildComponent Footer="@GenerateFooter()" />
@code {
// Your Method that will generate footer for you
private RenderFragment GenerateFooter() {
return builder => {
builder.OpenComponent(0, typeof(YourFooterComponent));
builder.AddAttribute(1, "YourRandomAttribute", "YourValueForAttribute")
builder.CloseComponent();
}
}
}
儿童组件
@*The place where you'd like to show your footer.*@
@Footer
@code{
[Parameter]
public RenderFragment Footer { get; set; }
}
如果你不想只为页脚创建另一个组件,你可以通过构建器来完成。OpenElement()。。。并创建所需的元素以及必需的样式和类,所有这些都可以使用属性来完成。布拉佐雷大学是一个网站,有很多很酷的东西。
如果它对你们有帮助,请告诉我,对未来也会更好。因为自从问题发布以来,这已经很晚了。