如何将 Blazor 组件实例传递给其他组件并渲染它?

问题描述 投票:0回答:1

我的应用程序中有一种工厂,我在其中创建各种对象的实例。所有对象都继承自同一个基类。 我现在尝试将此派生的实例传递到组件中,并希望显示内容。 我尝试用 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 有任何连接。

有没有办法创建一个组件的实例,并动态地把它交给一个,我称之为父组件,并在父组件中显示它?

asp.net-core blazor components server-side-rendering dynamically-generated
1个回答
0
投票

您不创建组件,而是渲染器创建。这是使用您的代码的演示:

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;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.