我有一个带有两个按钮的Blazor服务器应用程序。第一个按钮在C#中调用MenuOpen
方法,第二个按钮在C#中调用TestJSInterop
方法。这是代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
@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.log
添加到从C#调用的每个方法中。当我按下按钮调用TestJSInterop
时,在控制台中得到以下结果:
测试
调用addEditorModel
调用addTab:参数为0
调用addEditorModel
调用addTab:参数为0
当我按下按钮呼叫MenuOpen
时,得到以下结果:
调用addEditorModel
调用addTab:参数为1
调用addEditorModel
调用addTab:参数为0
调用addEditorModel
调用addTab:参数为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事件(例如click事件)会导致您的组件重新呈现。
如果您需要重新渲染组件以查看所做的更改
否则,您将必须调用StateHasChanged方法
如果您的应用是预渲染(render-mode =“ ServerPrerendered”),则组件将渲染两次,因此您可能会在控制台窗口中看到两次打印的消息。还行吧。
希望对您有所帮助...如果您没有解决问题,请发布代码的完整回购单,我将尽力帮助您。