背景: 我们有一个包含以下 3 个文件的 Blazor 应用程序:
ChildComponent.razor
<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.razor
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.razor,如下所示:
<ParentComponent Text="Hello World"></ParentComponent>
我们在这里不使用 <ParentFooter></ParentFooter>
,因为页脚是可选的。
问题:
我们在浏览器的控制台中得到一个异常:
<块引用>未处理的异常渲染组件:委托给一个实例 方法不能有 null 'this'(参数 'this')
可能的解决方案:
在文件 ParentComponent.razor 中,我们通过引用传递页脚并进行 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 传递给子组件?
答案 0 :(得分:0)
使用 CascadingValue
有效:
ParentComponent.razor:
<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.razor:
<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; }
}
Test.razor:
<ParentComponent Text="Hello World">
@* <ParentFooter>Footer</ParentFooter> // <- Optional *@
</ParentComponent>
答案 1 :(得分:0)
我认为,如果您想使用 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; }
}
如果您不想为页脚创建另一个组件,您可以通过 builder.OpenElement()... 并创建您需要的元素以及必需的样式和类,所有这些都可以使用属性来完成。 BlazoreUniversity 是一个网站,里面有很多很酷的东西。
如果它对您有帮助,请告诉我,对未来也更好。因为这已经很晚了,因为问题已经发布了。
答案 2 :(得分:-1)
您是否尝试在子组件中将参数设置为默认值 所以它看起来像这样
<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链接
问候,