为Blazor中子菜单中的DOM元素调用JS Interop函数



我正试图调用一个JS函数,该函数在Blazor中创建用户点击JS Interop时的模态。问题是,该函数正在为Blazor子菜单中的DOM元素使用onclick事件。当DOM元素在侧导航栏的子菜单之外时,它工作正常。当我将该元素放入子菜单时,Blazor抱怨它是cannot set property 'onclick' of null

这是我的导航栏HTML和JS互操作代码

@inject IJSRuntime JS;
<div class="top-row pl-4 navbar navbar-dark">
<a class="navbar-brand" href="">Test</a>
<button class="navbar-toggler" @onclick="ToggleNavMenu">
<span class="navbar-toggler-icon"></span>
</button>
</div>
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
<ul class="nav flex-column">
<li class="nav-item px-3">
<NavLink class="nav-link" href="/" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-3">
<NavLink class="nav-link" @onclick="()=>expandSubNav = !expandSubNav">
<span class="oi oi-fork" aria-hidden="true"></span> AccountPage
</NavLink>
@if (expandSubNav)
{
<ul  class="nav flex-column" id="submenu">
<li class="nav-item px-3">
<a class="expand-menu" href="page">
<span>element1</span>
</a>
</li>
<li class="nav-item px-3">
<a class="expand-menu" href="page">
<span>element2</span>
</a>
</li>
<li class="nav-item px-3">
<a class="expand-menu" href="page">
<span>element3</span>
</a>
</li>
<li class="nav-item px-3">
<a class="expand-menu">

<div   id="addBtn" ><span class="oi oi-plus" aria-hidden="true"></span> Add Element</div>
</a>
</li>


</ul>
}
</li>


</ul>
</div>
<div id="myModal" class="modal">
<!-- Modal content -->
<div class="modal-content">
<h1 class="modal-title">
<b>Add Element Here</b>
</h1>
<input id="addelementtext" type="text" />
<button id="add">Add</button>
<button type="button" class="btn btn-defaultcloseissue" id="closebtn" data-dismiss="modal" onclick="">Close</button>

</div>
</div>


</div>
</div>
@code { private bool collapseNavMenu = true;
private bool expandSubNav;
private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{

if (firstRender)
{

await JS.InvokeVoidAsync("createModal");

}
}
}

我正在尝试使用onclick与这个id元素

<li class="nav-item px-3">
<a class="expand-menu">

<div   id="addBtn" ><span class="oi oi-plus" aria-hidden="true"></span> Add Element</div>
</a>
</li>

它在它创建的子菜单中。当我把它放在子菜单之外的主导航菜单中时,JS函数没有抱怨,它工作得很好。

我也试过做这个

protected override async Task OnAfterRenderAsync(bool firstRender)
{

if (firstRender)
{
if (expandSubNav)
{
await JS.InvokeVoidAsync("createModal");
}
}
}

这将停止错误,但单击元素不会有任何作用。我该怎么着手解决这个问题?我正在尝试研究Blazor生命周期,因为我觉得这是一个渲染问题,但我很难理解我能做什么。

这也是我试图调用的JS函数

window.createModal = function createModal() {
var modal = document.getElementById("myModal");
// Get the button that opens the modal
var btn = document.getElementById("addBtn");
var closebtn = document.getElementById("closebtn");

// When the user clicks the button, open the modal
btn.onclick = function () {
modal.style.display = "block";
}

// When the user clicks anywhere outside of the modal, close it
window.onclick = function (event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
closebtn.onclick = function (event) {
modal.style.display = "none";
}
}

您的第一个错误cannot set property 'onclick' of null是因为在第一次呈现导航栏时未展开子导航栏部分,所以在调用var btn = document.getElementById("addBtn");时尚未在DOM中找到addBtn元素

第二个问题是因为if()语句在第一次渲染时只运行一次,而expandSubnav为false。所以你的await JS.InvokeVoidAsync("createModal");行永远不会被执行。

如果您注意到在@code块中有一种切换collapseNavMenu:的方法

private void ToggleNavMenu()
{
collapseNavMenu = !collapseNavMenu;
}

如果您做了类似的事情,但对于expandSubnav,您可以将其作为挂接createModal代码的机会。你只想做一次,所以你可能也想记录一下。类似于:

private bool modalCreated = false;
private void ToggleSubNav()
{
expandSubnav = !expandSubnav;
if(!modalCreated)
{
await JS.InvokeVoidAsync("createModal");
modalCreated = true;
}
}

然后将其连接到NavLink:

<NavLink class="nav-link" @onclick="ToggleSubNav">
<span class="oi oi-fork" aria-hidden="true"></span> AccountPage
</NavLink>

相关内容

  • 没有找到相关文章

最新更新