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

Posted

技术标签:

【中文标题】当我只告诉它调用一个函数时,Blazor Server 应用程序中的 JSRuntime.InvokeVoidAsync 调用多个函数【英文标题】:JSRuntime.InvokeVoidAsync in Blazor Server app calling multiple functions when I only tell it to call one 【发布时间】:2020-08-02 04:50:32 【问题描述】:

我有一个带有两个按钮的 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 中,我已将 console.logs 添加到从 C# 调用的每个方法中。当我按下按钮调用TestJSInterop 时,我在控制台中得到以下结果:

测试

调用 addEditorModel

调用addTab:参数为0

调用 addEditorModel

调用addTab:参数为0

当我按下按钮呼叫MenuOpen,我得到这个结果:

调用 addEditorModel

调用addTab:参数为1

调用 addEditorModel

调用addTab:参数为0

调用 addEditorModel

调用addTab:参数为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
        
    

    只有 UI 事件(例如点击事件)会导致您的组件重新呈现。 如果您需要重新渲染组件以查看所做的更改 否则,您将不得不调用 StateHasChanged 方法

    如果您的应用正在预渲染 (render-mode="ServerPrerendered" ),您的组件会被渲染两次,因此您可能会在控制台窗口中看到两次打印的消息。没关系。

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

【讨论】:

这就是问题所在,添加 if(firstRender) 解决了它。

以上是关于当我只告诉它调用一个函数时,Blazor Server 应用程序中的 JSRuntime.InvokeVoidAsync 调用多个函数的主要内容,如果未能解决你的问题,请参考以下文章

CORS错误Azure函数与B2C-Blazor

在 html 属性中调用 blazor 中的异步方法

调用 jquery/ajax 函数时出错

抑制触发的 Blazor 输入事件

当我在函数中调用函数时,它会跳过代码并终止程序?

为 Blazor WebAssembly 中的所有 blazor 页面实例化一个对象?