简体   繁体   English

将 Blazor 组件渲染到现有 div 中(Blazor 无权访问)

[英]Render Blazor component into existing div (that Blazor has no access to)

I'm using Blazor Server together with a React app for the layout part.我将 Blazor 服务器与 React 应用程序一起用于布局部分。

When Blazor starts up it calls the JSInterop to start up a React component.当 Blazor 启动时,它会调用 JSInterop 来启动一个 React 组件。 The React component basically creates a whole bunch of elements inside its layout (the ids of those are provided through the initial call). React 组件基本上在其布局中创建了一大堆元素(这些元素的 id 是通过初始调用提供的)。

My question is how I can tell Blazor to render components into those div-placeholders?我的问题是如何告诉 Blazor 将组件渲染到那些 div 占位符中?

The topics I was able to find always seem to have the html-code of the container being available in Blazor (and then using renderfragment).我能够找到的主题似乎总是在 Blazor 中提供容器的 html 代码(然后使用渲染片段)。 But in this scenario all I have is the placeholder id - the actual element is not known in Blazor.但在这种情况下,我所拥有的只是占位符 id - Blazor 中不知道实际元素。

Below the code (not using the react library here but instead creating a div within JS so that it's a cleaner example).在代码下方(此处不使用 react 库,而是在 JS 中创建一个 div 以便它是一个更简洁的示例)。 The main question is around the ***-section that gets called once JS has rendered the div - how can I tell Blazor to acknowledge that div element, or tell Blazor to find it, and to render components into it?主要问题是在 JS 渲染 div 后调用的 *** 部分 - 我如何告诉 Blazor 承认该 div 元素,或者告诉 Blazor 找到它,并将组件渲染到其中?

Index.razor索引.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 successrendermessage)
    {
        // ***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();
    }
    
}

And here is the JS code:这是JS代码:

export function CreateDiv(id, dotNetObj) {
$("body").append("<div id='" + id + "'></div>");
dotNetObj.invokeMethodAsync('SuccessRender', true);
}

This isn't an answer, but some information as you obviously want to go down this route.这不是答案,而是一些信息,因为您显然希望 go 沿着这条路线走下去。

You can in fact have multiple root components on a page.实际上,您可以在一个页面上拥有多个根组件。

index.html索引.html

add the extra divs with unique ids:添加具有唯一 ID 的额外 div:

....
    <div id="app">Loading...</div>

    <div id="app1">Loading...</div>

    <div id="app2">Loading...</div>

    <div id="app3">Loading...</div>
....

Program.cs程序.cs

Add the following:添加以下内容:

...
    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 (or your own custom Layout set up) it gets used by the first component App MainLayout.razor(或您自己的自定义布局设置)它被第一个组件App使用

@inherits LayoutComponentBase
@Body

Fire it up and you should get this:启动它,你应该得到这个: 在此处输入图像描述

All of the ids must exist in the startup page.所有 id 都必须存在于启动页面中。 Each could register with a management service and....每个人都可以注册管理服务并......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM