我想测试是否可以动态创建Blazor组件。
我找不到任何办法。我已经对this link上的一些动态内容进行了实验,但结果并没有结果。
答案 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
}