繁体   English   中英

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

[英]Why Blazor app showing an error with any page reload

我正在使用 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);
}

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

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

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

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

我试图做到这一点:

@inject IComponentContext ComponentContext
@functions{
    protected override void OnAfterRender()
    {
        if(ComponentContext.IsConnected)
        {
            //adding scripts
        }
    }
}

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

在您的代码示例中,有两个问题。

@inject IJSRuntime Js;

@functions {
    protected override async void OnAfterRender()
    {
        await Js.InvokeAsync<object>("addScriptFile","~/js/myFile.js");
    }
}

首先,您应该使用code而不是functions Code特定于Blazor组件, functions用于Razor Pages和MVC。

其次,永远不要在Blazor中使用async void ,该规则的例外是在事件处理程序中运行异步代码。 有关更多信息,请参见本文

第三,在脚本位置的开头有~字符。 该角色不适用于Blazor(我认为反而是毫无意义的),仅对MVC和Razor Pages有效。 如果要从应用程序的根目录加载脚本,则只需使用/ ,如果要从相对位置加载脚本,则不要在该位置添加前缀。

因此,我认为您的代码应如下所示。

@inject IJSRuntime Js;
@inject IComponentContext ComponentContext

@code {
    protected override async Task OnAfterRenderAsync()
    {
        if (!ComponentContext.IsConnected)
        {
            return;
        }

        await Js.InvokeAsync<object>("addScriptFile","/js/myFile.js");
    }
}

试试这个代码:

@using Microsoft.AspNetCore.Components
@using Microsoft.JSInterop
@inject IComponentContext ComponentContext
@inject IJSRuntime JSRuntime

protected override async Task OnAfterRenderAsync()
    {

        if (!ComponentContext.IsConnected)
        {
            return;
        }

     await JSRuntime.InvokeAsync<object>("addScriptFile","~/js/myFile.js");



    }

祝好运...

暂无
暂无

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

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