将 Blazor 组件渲染到现有 div(Blazor 无权访问)
Posted
技术标签:
【中文标题】将 Blazor 组件渲染到现有 div(Blazor 无权访问)【英文标题】:Render Blazor component into existing div (that Blazor has no access to) 【发布时间】:2021-07-17 16:50:31 【问题描述】:我将 Blazor Server 与 React 应用程序一起用于布局部分。
当 Blazor 启动时,它会调用 JSInterop 来启动 React 组件。 React 组件基本上在其布局中创建了一大堆元素(这些元素的 id 是通过初始调用提供的)。
我的问题是如何告诉 Blazor 将组件渲染到那些 div 占位符中?
我能够找到的主题似乎总是在 Blazor 中提供容器的 html 代码(然后使用渲染片段)。但在这种情况下,我只有占位符 id - Blazor 中不知道实际元素。
在代码下方(此处不使用 react 库,而是在 JS 中创建一个 div,这样它是一个更简洁的示例)。主要问题是在 JS 呈现 div 后调用的 *** 部分 - 我如何告诉 Blazor 确认该 div 元素,或告诉 Blazor 找到它,并将组件呈现到其中?
Index.razor
@page "/"
@using Microsoft.Extensions.Configuration
@inject IConfiguration Config
@inject IJSRuntime Jsr
@implements IDisposable
<div></div>
@code
private DotNetObjectReference<Index> objectReference;
[JSInvokable]
public void SuccessRender(object succes-s-rendermessage)
// ***Here is where it should call the render function.***
public override Task SetParametersAsync(ParameterView parameters)
objectReference = DotNetObjectReference.Create(this);
return base.SetParametersAsync(parameters);
protected override async Task OnAfterRenderAsync(bool firstRender)
if (firstRender)
await Jsr.InvokeVoidAsync("Library.CreateDiv", "uuid1", objectReference);
await base.OnAfterRenderAsync(firstRender);
public void Dispose()
objectReference?.Dispose();
这里是JS代码:
export function CreateDiv(id, dotNetObj)
$("body").append("<div id='" + id + "'></div>");
dotNetObj.invokeMethodAsync('SuccessRender', true);
【问题讨论】:
如果没有看到您的原始代码,我们将不知道如何对您现有的代码库进行更改。请发minimal reproducible example,并详细说明需要修改的地方。 道歉 - 添加了代码。 因此,如果我做对了,您就是在使用 jQuery/React 创建一个 DOM,然后让 Blazor 将数据放入被操纵的 DOM 中。这种情况的问题在于谁拥有 DOM 的主版本。 Blazor 不知道您的 id div 的存在,所以它不能用它做任何事情。是什么促使您使用 React 创建布局? @MrCakaShaunCurtis 我正在尝试使用我非常喜欢的 react 的 flexlayout 库 (github.com/caplin/FlexLayout)。我在 Blazor 世界中没有找到任何干净的东西。我理解你的观点,但它暗示 Blazor 总是希望任何 JS 小部件成为最终组件,而没有任何嵌套在里面(至少从 Blazor 的角度来看)? Blazor 仍然是拥有根的那个。但随后 react 在占位符 div 内创建一个组件,然后在该组件内我想放置 Blazor 项目。 @klarC “混合”框架几乎是不可能的,因为每个人都想控制 DOM。您正在寻找的是您最喜欢的布局工具的 Blazorized 版本,它可能不存在,您想编写它。您可能必须做出选择。 【参考方案1】:这不是一个答案,而是一些你显然想走这条路的信息。
实际上,您可以在一个页面上拥有多个根组件。
index.html
添加具有唯一 ID 的额外 div:
....
<div id="app">Loading...</div>
<div id="app1">Loading...</div>
<div id="app2">Loading...</div>
<div id="app3">Loading...</div>
....
程序.cs
添加以下内容:
...
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<SurveyPrompt>("#app1");
builder.RootComponents.Add<SurveyPrompt>("#app2");
builder.RootComponents.Add<SurveyPrompt>("#app3");
...
MainLayout.razor(或您自己的自定义布局设置)它被第一个组件使用App
@inherits LayoutComponentBase
@Body
启动它,你应该得到这个:
所有 id 都必须存在于启动页面中。每个人都可以注册管理服务并....
【讨论】:
非常感谢您的建议。你知道这是否也可以在组件内动态工作吗?这意味着一个新的根可以在一个组件中开始吗?例如,这将允许生成动态选项卡。 你不能在一个组件中启动一个新的根组件,但是如果你的意思是,我可以有一个占位符来动态加载组件吗?是的。以上是关于将 Blazor 组件渲染到现有 div(Blazor 无权访问)的主要内容,如果未能解决你的问题,请参考以下文章
将服务器端 Blazor 添加到现有 MVC Core 应用程序
从 JavaScript 渲染 Blazor 组件 - 如何在组件渲染后从 JavaScript 更新 Blazor 组件参数