Asp.net core 在用户内容中定位Blazor组件
我需要在用户提供的内容中动态放置Blazor组件。本质上,该组件应该使用一些UI元素扩展用户提供的标记 假设用户提供了一些内容,其中可以包含一个“问候容器”元素,组件应该在该元素中插入一个问候按钮 我目前的解决方案是调用一个JavaScript函数,在AfterRenderAsync中移动Asp.net core 在用户内容中定位Blazor组件,asp.net-core,blazor,blazor-server-side,asp.net-blazor,Asp.net Core,Blazor,Blazor Server Side,Asp.net Blazor,我需要在用户提供的内容中动态放置Blazor组件。本质上,该组件应该使用一些UI元素扩展用户提供的标记 假设用户提供了一些内容,其中可以包含一个“问候容器”元素,组件应该在该元素中插入一个问候按钮 我目前的解决方案是调用一个JavaScript函数,在AfterRenderAsync中移动中的DOM元素(下面是完整的代码)。它似乎工作得很好,但在Blazor中,操作DOM元素似乎是不受鼓励的,因为它会影响扩散算法。我有几个问题要问: 像这样移动DOM元素有多糟糕?它是否会导致性能问题、功能问题或
中的DOM元素(下面是完整的代码)。它似乎工作得很好,但在Blazor中,操作DOM元素似乎是不受鼓励的,因为它会影响扩散算法。我有几个问题要问:
像这样移动DOM元素有多糟糕?它是否会导致性能问题、功能问题或某些未定义的行为
有没有更好的方法可以在不使用JavaScript的情况下实现相同的结果?我曾考虑使用RenderTreeBuilder
来实现这一点,但它似乎不是为此目的而设计的,因为建议使用硬编码序列号,这在处理编译时未知的动态内容时似乎是不可能的
当前解决方案代码:
迎宾剃刀
@page”/greeter
@注入IJSRuntime JSRuntime;
@((MarkupString)UserContentMarkup)
切换问候语
@如果(是否可见问候语){
你好,@Name
}
@代码{
[参数]
公共字符串UserContentMarkup{get;set;}
[参数]
公共字符串名称{get;set;}
私人布尔正在欢迎可见;
私有void ToggleGreeting()
{
isGreetingVisible=!isGreetingVisible;
}
AfterRenderAsync(bool firstRender)上受保护的重写异步任务
{
等待JSRuntime.InvokeVoidAsync(“moveGreetingToContainer”);
}
}
_Host.cshtml
window.moveGreetingToContainer=()=>{
var greeting=document.getElementById(“greeting”);
var container=document.getElementById(“问候容器”);
容器.儿童(问候语);
}
UserContentTest.razor
@page”/userContentTest
@注入IJSRuntime JSRuntime;
测试用户内容
@代码{
私有字符串userContentMarkup=“一些HTML文本,后跟问候语和更多文本”;
}
预期结果(单击“切换问候语”后):
一些HTML文本,后跟问候语
切换问候语
你好,约翰
还有更多的文字
好问题-是的,使用JS移动dom元素非常糟糕,因为Blazor看不到您对dom所做的更改
您可以做的是切换到使用RenderFragment
,更具体地说是RenderFragment
,这是一种将提供更多标记作为参数的标记
在第二行,我调用UserContentMarkup方法(这是一个RenderFragment
)并将
内容作为上下文
参数传递
注意:它被包装在一个
元素中,这实际上是一种将HTML嵌入C#中的方式。它不会向页面呈现
元素
迎宾剃刀
@用户内容标记(
@
切换问候语
@如果(是否可见问候语){
你好,@Name
}
)
@code{
[参数]
公共RenderFragment UserContentMarkup{get;set;}
[参数]
公共字符串名称{get;set;}
私人布尔正在欢迎可见;
私有void ToggleGreeting()
{
isGreetingVisible=!isGreetingVisible;
}
}
UserContentTest.razor
在这里,您可以看到两种使用问候者的方法—在页面中使用标记,或者使用code
方法
测试用户内容
@*使用标记来提供用户内容-@上下文是按钮所在的位置*@
一些HTML文本,后跟问候语
@上下文和更多文本
@*使用一种方法来提供用户内容-@上下文就是按钮所在的位置*@
此code
方法可能会令人困惑-它是一个RenderFragment
,这意味着它必须是一个接受RenderFragment
作为其唯一参数的方法,并返回一个RenderFragment
——在本例中返回的RenderFragment
是用
包装的标记,以明确它是标记
@code
{
RenderFragment用户内容
=>context=>@Some-stuff@context-more-stuff;
}
请在此处试用:谢谢!这看起来几乎正是我需要的。唯一的附加问题是,这个字符串“Some stuff@context more stuff”能否像从数据库加载一样动态提供?因为它是我们事先不知道的用户内容是的,但是您需要一个上下文占位符,并在运行时替换它。有这样做的例子吗?从文档中我可以发现,似乎所有的标记都必须在编译时提供,这样“Blazor编译器”就可以将其翻译成html。但是,如果有任何方法可以动态地获取它,那就真的很难了。我猜你的意思是在呈现组件后,为上下文设置一个占位符,并通过JavaScript替换它?没有JS就不行。但是,只为pre和post设置两个渲染片段可能更容易