首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >启用动态根组件/错误:此应用程序中未启用动态根组件

启用动态根组件/错误:此应用程序中未启用动态根组件
EN

Stack Overflow用户
提问于 2021-09-24 17:44:26
回答 1查看 1.2K关注 0票数 4

我希望从javascript中呈现一个Blazor组件。参见https://devblogs.microsoft.com/aspnet/asp-net-core-updates-in-net-6-rc-1/“从JavaScript呈现Blazor组件”

我有一个HTML文件:

代码语言:javascript
复制
<script src="/_framework/blazor.server.js"></script>
<div id="counter"></div>

<script>
    async function ready() {
        let containerElement = document.getElementById('counter');
        await Blazor.rootComponents.add(containerElement, 'counter', { incrementAmount: 10 });
    }
    document.addEventListener("DOMContentLoaded", ready);
</script>

然后去做

代码语言:javascript
复制
builder.Services.AddServerSideBlazor(options =>
{
    options.RootComponents.RegisterForJavaScript<Counter>("counter");
});

错误消息(JavaScript):

代码语言:javascript
复制
test.html:14 Uncaught (in promise) Error: Dynamic root components have not been enabled in this application.
    at E (blazor.server.js:1)
    at Object.add (blazor.server.js:1)
    at HTMLDocument.ready (test.html:8)

如何启用动态根组件?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-28 09:27:58

发生此错误的原因是文档加载和Blazor“准备好”处理添加组件的请求之间的延迟。

似乎没有任何正式的文档化的解决方案,但类似的事情是可能的。

将Blazor改为手动启动:

index.html

代码语言:javascript
复制
<script src="_framework/blazor.webassembly.js" autostart="false"></script>
<script src="js/script.js" defer></script>

启动Blazor,然后尝试添加组件-重复直到成功。

script.js

代码语言:javascript
复制
document.addEventListener("DOMContentLoaded", startBlazor)

function startBlazor() {
    Blazor
        .start()
        .then(() => {
            requestAnimationFrame(AddBlazorComponents)
        })
        .catch((error) => console.error(error));
}

let attempts = 0
const maxAttempts = 120 // arbitrary choice

function AddBlazorComponents() {
    if (attempts > maxAttempts) {
        // give up after trying too many times
        console.error("Could not load Blazor components.")
        return
    }

    const containerElement = document.querySelector('#app')
    Blazor.rootComponents.add(containerElement, 'app', {})
        .catch(reason => {
            if (reason.message === "Dynamic root components have not been enabled in this application.")
                requestAnimationFrame(AddBlazorComponents)
            else
                console.error(reason)
        })
    attempts++
}

更好的解决方案?

您可以在应用程序启动后,向您的JSInterop代码中添加一个.NET调用,以方便这一点--但是对于不同的托管模式: Blazor / Blazor WebAssembly,情况就不同了。

更好的做法可能是,使用预注册组件的方法对aspnetcore回购进行PR,以便框架在准备就绪时加载。

更新:2021年9月29日

事实证明,有一些目前没有文档的功能,在这里有帮助。我在@Swimburger的github问题上抄袭了我的评论如下:

对于动态组件来说,新的JavaScript初始化器afterStarted被调用(可能)太早了,但事实证明,您可以传递一个初始化程序来调用一个动态组件--但是它没有很好的文档记录或直观的imho。

为此,我在program.cs中更改了应用程序的启动方式(添加了program.cs):

builder.RootComponents.RegisterForJavaScript<App>(identifier: "app", javaScriptInitializer: "loadApp");

然后,这就是它不直观的地方,我向我的模块(如afterStarted)添加了一个名为loadApp的导出,但它没有被调用。

原来,只有当我将loadApp添加到window对象时,才能找到它,所以我将它添加到index.html中。

代码语言:javascript
复制
<script src="_framework/blazor.webassembly.js"></script>
<script>
    window.loadApp = function (component,params) {
        let containerElement = document.querySelector('#app')
        window.Blazor.rootComponents.add(containerElement, component, params)
    }
</script>

这感觉好像我在如何导出我的自定义初始化程序中缺少了一些东西,或者它确实需要直接添加到window中,这似乎很奇怪……

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69319216

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档