为什么 Blazor 应用在​​任何页面重新加载时都会显示错误

Ami*_*mam 4 c# blazor

我正在使用 Blazor 技术开展项目。我有时需要使用一些 JS 代码,并且需要在每个页面中包含不同的 js 文件,据我所知,唯一的方法是使用 JS 函数和 Blazor JS 调用添加它。所以我所做的是:在 _Host.razor 中

function addScriptFile(fileName){
    var script = document.createElement("script");
    script.setAttribute("type", "text/javascript");
    script.setAttribute("src", file);
    document.getElementById(divName).appendChild(script);
}
Run Code Online (Sandbox Code Playgroud)

然后在每个页面(组件)中:

@inject IJSRuntime Js;
@functions{
    protected override async void OnAfterRender()
    {
        await Js.InvokeAsync<object>("addScriptFile","~/js/myFile.js");
    }
}
Run Code Online (Sandbox Code Playgroud)

它工作正常,但如果重新加载页面就会出现问题。它会抛出错误 System.InvalidOperationException: 此时无法发出 JavaScript 互操作调用。这是因为组件正在预渲染,并且页面尚未加载到浏览器中,或者电路当前已断开连接。组件必须将任何 JavaScript 互操作调用包装在条件逻辑中,以确保在预渲染期间或客户端断开连接时不会尝试这些互操作调用。

我从这个错误中了解到,我试图在渲染完成之前调用一些 javascript 代码。所以我使用 IComponentContext 来确保服务器已连接。在解决此问题的过程中,我创建了一个没有任何 JS 文件的新 Blazor 项目,但它在重新加载页面时引发了相同的错误

我试着做这个:

@inject IComponentContext ComponentContext
@functions{
    protected override void OnAfterRender()
    {
        if(ComponentContext.IsConnected)
        {
            //adding scripts
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何让 JS 以合适的方式与 Blazor 一起工作?以及如何修复该错误?

Chr*_*nty 5

在您的代码示例中,存在几个问题。

\n\n
@inject IJSRuntime Js;\n\n@functions {\n    protected override async void OnAfterRender()\n    {\n        await Js.InvokeAsync<object>("addScriptFile","~/js/myFile.js");\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

首先,你应该使用codenot functionsCode特定于 Blazor 组件,functions用于 Razor Pages 和 MVC。

\n\n

其次,切勿在 Blazor 中使用async void,该规则的例外是在事件处理程序中运行异步代码。看这篇文章了解更多信息。

\n\n

第三,角色~位于脚本位置的开头。这个角色不能与 Blazor 一起使用(在我看来,无论如何都是毫无意义的),它仅对 MVC 和 Razor 页面有效。如果您想从应用程序的根目录加载脚本,那么只需使用/,如果您想从相对位置加载脚本,则不要在该位置添加任何前缀。

\n\n

综上所述,我认为您的代码应该如下所示。

\n\n
@inject IJSRuntime Js;\n@inject IComponentContext ComponentContext\n\n@code {\n    protected override async Task OnAfterRenderAsync()\n    {\n        if (!ComponentContext.IsConnected)\n        {\n            return;\n        }\n\n        await Js.InvokeAsync<object>("addScriptFile","/js/myFile.js");\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

  • 您需要使用 VS Preview 进行 Blazor 开发。有些功能目前仅在预览版中可用。使用异步不是问题,而是返回类型为 void 而不是 Task 的事实。 (2认同)