我的应用程序中有一种工厂,我在其中创建各种对象的实例。所有对象都继承自同一个基类。 我现在尝试将此派生的实例传递到组件中,并希望显示内容。 我尝试用 RenderFragment 来实现它。这适用于初始视图。然而,不久之后 Blazor 再次调用我的派生构造函数,并且我在 html 中的实例是一个新实例。
我需要它能够对与我的衍生物的交互做出反应。但是,再次调用构造函数会产生一个实例,该实例当然不再包含与我的 EventHandler 的任何连接或调用构造函数时最初给出的参数。
ChildBase.cs
public class ChildBase : ComponentBase
{
public EventHandler? OnClick = null;
}
Child1.剃刀
@inherits ChildBase
<div style="width:100px; height: 200px; background:red;>
<button @onClick=OnClick>Click Child 1</button>
</div>
@code{
private async Task OnClick()
{
// do something
if(base.OnClick != null)
{
base.OnClick(this, EventArgs.Empty);
}
}
}
Child2.razor.cs
@inherits ChildBase
<div style="width:200px; height: 100px; background:yellow;>
<button @onClick=OnClick>Click Child 2</button>
</div>
@code{
private async Task OnClick()
{
// do something other
if(base.OnClick != null)
{
base.OnClick(this, EventArgs.Empty);
}
}
}
第1页.razor
<button @onClick="ShowChild1">One</button>
<button @onClick="ShowChild2">Two</button>
<br/>
<br/>
@if(ContentFragment != null)
{
@ContentFragment
}
@code{
private RenderFragment? ContentFragment;
private void ShowChild1()
{
ChildBase child = new Child1();
child.OnClick += OnChildClicked;
ContentFragment = createRenderFragment(child);
}
private void ShowChild2()
{
ChildBase child = new Child2();
child.OnClick += OnChildClicked;
ContentFragment = createRenderFragment(child);
}
private void OnChildClicked(object? sender, EventArgs e)
{
//Do something
}
private RenderFragment createRenderFragment(ChildBase child) => builder =>
{
builder.OpenComponent(0, child.GetType());
builder.CloseComponent();
};
}
Child1 和 Child2 的视图和内容完全不同。
当您单击相应的按钮时,您将看到在相应子级和子级基类的构造函数中带有断点的双重调用。视图中显示的组件不再与 ClickHandler 有任何连接。
有没有办法创建一个组件的实例,并动态地把它交给一个,我称之为父组件,并在父组件中显示它?
您不创建组件,而是渲染器创建。这是使用您的代码的演示:
ChildBase
使用 EventCallback
而不是 event
public class ChildBase : ComponentBase
{
[Parameter] public EventCallback OnClick { get; set; }
}
Child1
[和 Child2]
@inherits ChildBase
<div style="m-2 p-2">
<button class="btn btn-primary" @onclick="OnClicked">Click Child 1</button>
</div>
@code{
private Task OnClicked()
{
return this.OnClick.InvokeAsync();
}
}
演示页面显示了构建渲染片段的一种方法。
@page "/"
@using Microsoft.AspNetCore.Components.Rendering
<div class="m-2 p-2">
<button class="btn btn-primary" @onclick="ShowChild1">One</button>
<button class="btn btn-danger" @onclick="ShowChild2">Two</button>
</div>
@_contentFragment
@code {
private RenderFragment? _contentFragment => BuildChild;
private Type _componentToRender = typeof(Child1);
private Task ShowChild1()
{
_componentToRender = typeof(Child1);
return Task.CompletedTask;
}
private Task ShowChild2()
{
_componentToRender = typeof(Child2);
return Task.CompletedTask;
}
private void BuildChild(RenderTreeBuilder builder)
{
builder.OpenComponent(0, _componentToRender);
builder.AddComponentParameter(1, "OnClick", Microsoft.AspNetCore.Components.EventCallback.Factory.Create(this, this.OnChildClicked));
builder.CloseComponent();
}
private Task OnChildClicked()
{
//Do something
return Task.CompletedTask;
}
}