当我只告诉它调用一个函数时,Blazor 服务器应用程序中的 JSRuntime.InvokeVoidAsync 调用多个函数

Mer*_*n04 6 javascript c# interop asp.net-core blazor

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

@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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

测试

调用addEditorModel

调用addTab:参数为0

调用addEditorModel

调用addTab:参数为0

当我按下呼叫按钮时MenuOpen,我得到以下结果:

调用addEditorModel

调用addTab:参数为1

调用addEditorModel

调用addTab:参数为0

调用addEditorModel

调用addTab:参数为0

我知道OpenNewTabC# 方法不会被多次调用,因为当我在那里放置断点并单击按钮进行调用时,TestJSInterop我没有到达断点。

JSRuntime.InvokeVoidAsync调用在OnAfterRenderAsync.

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

Isa*_*aac 6

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

  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
        }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 只有 UI 事件(例如单击事件)才会导致组件重新呈现。如果您需要重新渲染组件才能查看所做的更改,则必须调用 StateHasChanged 方法

  3. 如果您的应用程序是预渲染的( render-mode="ServerPrerendered" ),您的组件会渲染两次,因此您可能会在控制台窗口中看到两次打印消息。还行吧。

希望这会有所帮助...如果您没有解决问题,请发布您的代码的完整存储库,我会尽力帮助您。