动态附加 blazor 组件

hul*_*ist 1 blazor

我可以在 C# 中创建 Blazor 组件的实例并随后附加它吗?或者可以从 C# 代码在 DOM 中动态创建组件并获取对其的引用吗?

我正在创建一个由 C# 代码触发的“弹出对话框”。

对话剃刀

<div>
    Dialog Text: @Text
</div>

@code{
    public string Text { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

尝试失败

<div>
    @foreach (var d in List)
    {
        <div>@d</div><!--this doesn't work since d is not a RenderFragment-->
    }
</div>

@code{
    public List<Dialog> List { get; set; } = new List<Dialog>();

    void AddDialog()
    {
        var d = new Dialog();
        d.Text = "Hello " + List.Count;
        List.Add(d);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里的问题是我还没有找到将 ComponentBase 实例附加到 DOM 上的方法。有没有办法获取RenderFragment?

第二个问题是子组件直到附加对话框之后才初始化,从而限制了首先可以执行的操作。

Isa*_*aac 5

这是另一种方法......

警报消息.razor

<div style="border: 1px solid red; width: 500px; height:auto; margin: 3px; 
  padding:0px;">
    <div style="height:auto; width:inherit; padding:5px; border: 1px solid 
    blue; text-align:right;">
        <span style="float:left">@Title</span>
        <a href="#" @onclick="@(() => Close.InvokeAsync(ID))" 
   role="button">X</a>
        <div><input type="text" value="@content" /></div>
    </div>
     <div style="padding:25px; ">@ChildContent</div> 

 </div>

@code {
  [Parameter]
  public int ID { get; set; }
  [Parameter]
  public string Title { get; set; }
  [Parameter]
  public RenderFragment ChildContent { get; set; }
  [Parameter]
  public EventCallback <int> Close {get; set;}

}
Run Code Online (Sandbox Code Playgroud)

AlertMessageGroup.razor

@using Microsoft.AspNetCore.Components.CompilerServices;


<h3>AlertMessageGroup</h3>
@if (alerts.Count > 0)
{
<p>Contains @alerts.Count AlertMessage Components</p>

@foreach (var alert in alerts)
 {
       <p>Alert ID: @alert.ID</p>

 }
}

<div>

    @foreach (var alert in alerts)
    {
        @RenderAlert(alert);

    }


</div>



@code {

List<Alert> alerts = new List<Alert>
        {
            new Alert{ ID = 1, Title = "First Message", Message = "This is my 
                                                            first message" },
            new Alert{ ID = 2, Title = "Second Message", Message = "This is 
                                                        my second message" },
            new Alert{ ID = 3, Title = "Third Message", Message = "This is my 
                                                             third message" }
        };


private RenderFragment RenderAlert(Alert alert) => builder =>
{

    builder.OpenComponent(0, typeof(AlertMessage));
    builder.AddAttribute(1, "ID", alert.ID);
    builder.AddAttribute(2, "Title", alert.Title);


    builder.AddAttribute(3, "ChildContent", (RenderFragment)((builder) =>
    {
        builder.AddContent(4, alert.Message);


    }
    ));

     builder.AddAttribute(5, "Close", EventCallback.Factory.Create<int>
                                          (this, RemoveAlertMessage));
     builder.CloseComponent();

  };



public void RemoveAlertMessage(int ID)
{

    alerts.Remove( alerts.Where(alert => alert.ID == ID).FirstOrDefault());
    StateHasChanged();
}


public class Alert
{
    public int ID { get; set; }
    public string Title { get; set; }
    public string Message { get; set; }

}

}
Run Code Online (Sandbox Code Playgroud)

用法

@page "/"

<AlertMessageGroup />
Run Code Online (Sandbox Code Playgroud)