在HTML字符串中动态替换Blazor组件

时间:2020-06-05 15:57:31

标签: c# dynamic blazor blazor-client-side

我想在从服务接收到的一些HTML文本中动态替换Blazor客户端组件。

例如,假设我收到以下字符串:

string htmlText = @"
<h1>Heading with {my component} inside it</h1>
";

我想用组件MyComponent替换花括号中的所有文本,该组件采用参数Text并呈现为<em>@Text</em>

最后我想获得的是:

<h1>Heading with <em>my component</em> inside it</h1>

我得到的最接近的方法是将字符串拆分为HTML部分和应替换为组件的部分(例如SplitText = htmlText.Split('{', '}');),然后在Blazor页面内的for循环中呈现它们:< / p>

@for (int i = 0; i < SplitText.Length; i++)
{
    if (i % 2 == 0)
    {
        @((MarkupString)SplitText[i])
    }
    else
    {
        <MyComponent Text="@SplitText[i]" />
    }
}

但这在Chrome中显示为:

<h1>Heading with </h1>
<em>my component</em>
inside it

我也尝试使用RenderFragment,但最终获得了相似的结果。

编辑:

我将添加一些上下文,以澄清我正在尝试做的事情。也许还有一些我没想到的更好的方法,也许可以稍微解释一下这样做的目的,可以帮助有人将我指向一个更好的方向。

这旨在构建一个Web应用程序,用户可以在其中使用将输出HTML(或Markdown可能)的丰富编辑器编写自己的笔记(某种)。编辑器还将允许插入一些特殊标签以链接到它们所写的其他注释。这些是示例中的大括号。文本将存储在数据库中并事先经过验证,因此不必担心语法不正确(例如大括号内或嵌套大括号内的HTML标记)。呈现文本后,特殊标签应替换为所涉及的组件,该组件将生成链接并处理更多功能(例如,将鼠标悬停在便笺预览上时弹出)。因此,这比仅添加<em>标签(如示例中所示)要复杂得多。

我认为使用JavaScript可以很容易地做到这一点,但是首先我想看看是否有可能使用纯Blazor做到这一点,因为它是一个非常有趣的新框架。

1 个答案:

答案 0 :(得分:0)

使用MarkupString有点棘手,因为Blazor引擎将自动关闭标签,而忽略没有相关打开标签的关闭标签。这就是您获得上面看到的输出的方式。

由于该服务为字符串提供了包含的标签,因此您可以将其与内部文本一起提供给组件,并执行一些智能的字符串工作以获取将正确呈现的标记字符串。

MyComponent.razor

@if (MarkupText != null )
{
    @((MarkupString)$"{FirstHalf}{InnerText}{SecondHalf}")
}

@code{

    [Parameter] public string MarkupText { get; set; }

    // Inner Text set with starting value, can be left blank if needed
    [Parameter] public string InnerText { get; set; } = "";

    public string FirstHalf => MarkupText.Substring(0, MarkupText.IndexOf("{"));
    public string SecondHalf => MarkupText.Substring(MarkupText.IndexOf("}") + 1);
}

然后将其与htmlText一起使用:

<MyComponent MarkupText="@htmlText" InnerText="<em>Something</em>" />

此输出变为:

其中包含内容的标题

这是一个简单的版本,应该可以使您有所了解,但是关键是要将标记字符串设置为一个连续的字符串,然后一次性将其转换为MarkupString,因此编译器正确放置标签。使用相同的方法,您可以扩展上述想法,进行一些非常繁重的字符串操作,并根据需要构建更多内容。

请注意,如果服务仅提供带有花括号的文本而没有提供标签,则也可以非常容易地使用RenderFragment概念来构造嵌套的组件,并且可以更好地分隔内容和演示文稿。通过接收不带标签的字符串,然后像我展示的那样将其拆分,您只需要有一个外部组件即可将字符串进行拆分,拆分,然后将第一部分和第二部分相应地放置在子组件周围,而Blazor可以以您期望的方式呈现它,根本不需要MarkupString。标签将位于外部组件中。不确定对您的服务输出有多少控制权,但这是需要考虑的事情。