Blazor服务器,条件元素+ JS调用

时间:2020-05-18 17:30:39

标签: asp.net-core blazor blazor-server-side

我有一个Blazor Server应用程序,它是一个多步骤“向导”形式。在执行每个相关步骤后,将调整状态,并通过条件语句显示/隐藏新的HTML(以下简单示例)。

if (IsStepSignature)
{
    <div>Signature HTML here</div>
}

一切正常。我的问题来自需要从上面动态生成的HTML上调用一些JS逻辑(例如,单击处理程序以连接外部JS库)。当我处理“下一步”单击时,我可以很好地调用JS ...但是它尚未从上方看到动态HTML。有没有一种方法可以调用一些JS并对其进行控制,以使其直到从C#代码执行中重绘页面后才执行?

Nik P的2020年5月18日更新 可以利用一些标志并使用OnAfterRenderAsync来控制此顺序。这确实可行,但确实需要往返于服务器的一些额外跃点。下面是我在执行此操作时看到的内容。这可能只是Blazor Server的本质,因为优点/缺点之一是一些已知的增加的聊天性。这些请求总计为2.5K,非常小。

CLIENT    -->    Browser Dispatch Event (NEXT CLICK)
Render    <--    SERVER
CLIENT    -->    Render Complete
Invoke JS <--    SERVER
CLIENT    -->    Invoke Complete

1 个答案:

答案 0 :(得分:2)

直到重新渲染之后,您所遇到的问题才与客户端HTML中根本不存在的元素有关。因此,执行此操作的一种方法是在C#代码中设置一个布尔标志,该标志表示在渲染后需要运行一些代码,并填充JS Interop所需的支持字段。每当需要运行JS互操作时,请将标志设置为true,将支持字段设置为JS互操作调用所需的值,然后执行一些可进行DOM差异计算的操作。 (即使StateHasChanged应该足够,但也可以像前面提到的那样有条件地添加项目)。然后,如下重写您的OnAfterRenderAsync方法:

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if(firstRender)
    {
        // any first render code
    }

    if(yourFlag)
    {
        YourJSInteropMethod(supportField1, supportfield2);
        yourflag = false;  
    }
}

此方法的简单之处在于,DOM更新将始终在OnAfterRenderAsync调用之前进行,因此您的HTML将使用JS定位的对象进行填充。