JSRuntime.InvokeVoidAsync 在 Blazor Server 应用中调用多个函数,而我只告诉它调用一个函数

JSRuntime.InvokeVoidAsync in Blazor Server app calling multiple functions when I only tell it to call one

我有一个带有两个按钮的 Blazor 服务器应用程序。第一个按钮调用C#中的MenuOpen方法,第二个按钮调用C#中的TestJSInterop方法。这是代码:

@inject IJSRuntime JSRuntime;

<!-- buttons -->

@code {
    List<int> tabs = new List<int>();

    protected override Task OnAfterRenderAsync(bool firstRender)
    {
        JSRuntime.InvokeVoidAsync("monacoInit");
        return base.OnAfterRenderAsync(firstRender);
    }

    async Task OpenNewTab(string title)
    {
        int newId = await JSRuntime.InvokeAsync<int>("addEditorModel", new object[]
        {
            title, "test", "test", "test"
        });
        tabs.Add(newId);
        await JSRuntime.InvokeVoidAsync("addTab", newId);
    }

    async Task MenuOpen()
    {
        await OpenNewTab("testing");
    }

    async Task TestJSInterop()
    {
        await JSRuntime.InvokeVoidAsync("console.log", "test");
    }
}

在 Javascript 中,我向从 C# 调用的每个方法添加了 console.log。当我按下按钮调用 TestJSInterop 时,我在控制台中得到以下结果:

test

call addEditorModel

call addTab: parameter is 0

call addEditorModel

call addTab: parameter is 0

当我按下按钮调用 MenuOpen 时,我得到了这个结果:

call addEditorModel

call addTab: parameter is 1

call addEditorModel

call addTab: parameter is 0

call addEditorModel

call addTab: parameter is 0

我知道OpenNewTab C# 方法没有被多次调用,因为当我在那里设置断点并单击按钮调用时 TestJSInterop 我没有到达断点。

JSRuntime.InvokeVoidAsync 调用在 OnAfterRenderAsync 中正常工作。

为什么我会出现这种行为?

我试图理解您的部分代码,但似乎我失败了。但是,您应该考虑以下几点:

  1. 每次渲染组件时都会执行 OnAfterRenderAsync 方法。它主要用于初始化 JavaScript 个对象。当你想初始化你的 JavaScript 对象时(我猜只有一次,对吧?),代码应该放在 if 语句中检查这是第一次:

    if( firstRender )
       {
           // Here's you place code that is executed only once
           // the parameter firstRender is evaluted to true only the first time 
           // the OnAfterRenderAsync method is executed
        }
    
  2. 只有 UI 事件(例如单击事件)会导致您的组件重新呈现。 如果您需要重新渲染组件以查看所做的更改 否则,您必须调用 StateHasChanged 方法

  3. 如果您的应用是预渲染 ( render-mode="ServerPrerendered" ),您的组件会渲染两次,因此您可能会在控制台 window 中看到消息打印两次。这个可以。

希望这对您有所帮助...如果您没有解决问题,请 post 完整的代码回购,我会尽力帮助您。