簡體   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