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
中正常工作。
为什么我会出现这种行为?
我试图理解您的部分代码,但似乎我失败了。但是,您应该考虑以下几点:
每次渲染组件时都会执行 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" ),您的组件会渲染两次,因此您可能会在控制台 window 中看到消息打印两次。这个可以。
希望这对您有所帮助...如果您没有解决问题,请 post 完整的代码回购,我会尽力帮助您。
我有一个带有两个按钮的 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
中正常工作。
为什么我会出现这种行为?
我试图理解您的部分代码,但似乎我失败了。但是,您应该考虑以下几点:
每次渲染组件时都会执行 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" ),您的组件会渲染两次,因此您可能会在控制台 window 中看到消息打印两次。这个可以。
希望这对您有所帮助...如果您没有解决问题,请 post 完整的代码回购,我会尽力帮助您。