Blazor - 如何动态创建组件

时间:2018-05-01 14:03:42

标签: c# asp.net-core blazor

我想测试是否可以动态创建Blazor组件。

我找不到任何办法。我已经对this link上的一些动态内容进行了实验,但结果并没有结果。

3 个答案:

答案 0 :(得分:7)

对于0.2版本,这是史蒂夫桑德森的答案:

我们将来会实现更好的API来构建RenderFragments,但是现在你可以

@CreateDynamicComponent();
@functions {
    RenderFragment CreateDynamicComponent() => builder =>
    {
        builder.OpenComponent(0, typeof(SurveyPrompt));
        builder.AddAttribute(1, "Title", "Some title");
        builder.CloseComponent();
    };
}

这些是非常低级的API(甚至没有记录),所以我们希望现在没有多少人需要这样做。更高级别的API将在稍后出现。

找到here

答案 1 :(得分:0)

对于Blazor的新手(像我这样),值得注意的是,您不一定需要动态添加组件,实际上,在大多数情况下您可能不需要。

以页面/组件的示例为例,该页面/组件显示一个销售订单,然后每个销售订单行都有一个子组件。您的剃须刀页面上可能有如下代码:

  @foreach (var salesOrderLine in _salesOrder.salesOrderlines)
  {
    <SalesOrderLine>@salesOrderLine</SalesOrderLine>
  };

如果您有一个添加了另一个销售订单行的按钮,则只需在按钮单击事件中将新记录添加到_salesOrder模型/视图模型中即可。 通常,单击按钮会触发重新渲染,因此页面应随后自动显示一个额外的SalesOrderLine组件。

这里的关键点(对于那些来自MVC背景的人)是,不需要像在MVC中那样尝试将新的HTML手动注入到DOM中或动态加载部分视图。为您做到这一点。

如果其他操作正在更改销售订单或销售订单行的状态,并且Blazor并未发现需要更新DOM本身的那部分,则可以通过添加以下行来对其进行微调: / p>

this.StateHasChanged();

进入您的方法以明确告诉Blazor事情已经改变,现在应该更新页面的呈现版本。

尽管MVC的剃刀页面和Blazor的剃刀页面在语法上相似,但Blazor模型在概念上更接近于React之类,而不是MVC,了解影子DOM的本质非常重要在后台。

This page has some good pointers有关Blazor中的数据绑定。

答案 2 :(得分:0)

当然,您也可以使用 BuildRenderTree 来做类似的事情,但通常不建议这样做,因为它会搞砸。 (Microsoft documentation)

public class CustomLabel: ComponentBase
{  
    [Parameter] public string Id { get; set; }
    [Parameter] public string? Label { get; set; }

    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        if (!string.IsNullOrEmpty(Label))
        {
            builder.OpenElement(1, "label");
            builder.AddAttribute(2, "for", Id);
            builder.AddAttribute(3, "class", "custom-css-classes-here");
            builder.AddContent(4, Label);
            builder.CloseElement();
        }
    }

    // another example: maybe you would have an "IsRequired" flag 
    // that would add an "*" after the label if set to true
}