如何推荐动态渲染Blazor组件?

8

我是一名新手,有基本的Angular和Vue.js经验,现在想学习Blazor。我希望能够渲染一个多态组件列表:

<ul>
    @foreach (fruit of fruits) 
         <li>HOW DO I RENDER FRUIT HERE??? </li> // render the fruit component
</ul>

@code {
   // Each member in the list is a subtype of Fruit
   var fruits = List<FruitComponent> {
       new PearComponent(),
       new AppleComponent()'
       new BananaComponent(),
       new RasberryComponent()
}

据我所知,有几种方法可以实现这一目标,但每种方法都有其不足之处。其中一个不常见的方法建议使用未经记录的API调用,这可能会在没有通知的情况下被弃用,但它似乎几乎是理想的。另一个建议在代码中发出标记,这将带来编写ASP.NET服务器控件的繁琐。最后,最常见的建议使用条件性标记,虽然非常简单,但它将呈现代码与其呈现的组件耦合起来。
我读过的大多数文档可能已经过时且不再相关。随着Blazor的正式发布,有什么推荐的方法来实现这个目标?

你想在 ???? 上要什么? - H H
@HenkHolterman,我只想渲染水果。 - ATL_DEV
好的,我忽略了组件后缀。但是你怎么写呢?只是使用BuildRenderTree()编写类,还是要编写一个PearComponent.razor?因为据我所知,这与构造函数参数不相符。 - H H
@HenkHolterman。我想呈现组件的razor文件。我会修改代码。是的,我不知道你不能使用ctor。我对Web框架之一的问题是它们经常强制你绕过语言内置的OO设施感到困扰。 - ATL_DEV
https://learn.microsoft.com/en-us/aspnet/core/blazor/advanced-scenarios?view=aspnetcore-3.1#manual-rendertreebuilder-logic - Jinjinov
2个回答

6

您需要创建一个RenderFragment,并将其用作多态组件的渲染器...我使用了默认的Blazor模板Counter组件作为父级(CounterParent),然后CounterChild继承CounterParent。希望这能帮到您!祝好!

@page "/"

@foreach (CounterParent counter in components)
{
    RenderFragment renderFragment = (builder) => { builder.OpenComponent(0, counter.GetType()); builder.CloseComponent(); };
    <div>
        <div>Before the component</div>
        @renderFragment
        <div>Afterthe component</div>
    </div>
}

@code
{
    List<CounterParent> components = new List<CounterParent>() { new CounterParent(), new CounterChild() };
}

欢迎!你在哪里看到它不受官方支持?据我所知,这是Blazor的核心概念! - Charles Deluxe
我在我的组件中使用了CSS隔离。但是类没有被加载。你有任何想法,我该如何解决这个问题吗? - Machine

2

您可以使用 switch 语句来检查类型。您可以在每个 case 中放置组件,或者按照您的喜好呈现 li。

<ul>
    @foreach (fruit in fruits)
    {
        switch(fruit)
        {
            case PearComponent p:
                <PearComponent ParameterOfSomeSort="p"></PearComponent>
                <li>Or render pears like this, if you want the li in it</li>
                break;
            case AppleComponent a:
                <AppleComponent></AppleComponent>
                break;
            case BananaComponent b:
                <BananaComponent></BananaComponent>
                break;
            case RaspberryComponent r:
                <RaspberryComponent></RaspberryComponent>
                break;
        }
    }
</ul>

1
正如我所提到的,这个特定的解决方案虽然简单直接,但是与所有的ComponentFruit子类型耦合在一起,而不仅仅是ComponentFruit。因此,在运行时无法注入未知的FruitComponent子类型。看来Blazor团队在这个问题上犯了一个错误。 - ATL_DEV

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接