У меня есть компонент blazor webassembly для модального всплывающего окна. Пока это работает, но закроется только при нажатии кнопки x, а не при выключении. Вот код, о котором идет речь
@using System.Threading.Tasks;
@if (IsVisible)
{
<div class = "modal-backdrop fade show"></div>
<div id = "myModal " class = "modal show" style = "display: block">
<div class = "modal-dialog" role = "document">
<div class = "modal-content">
<div class = "modal-header">
<h5 class = "modal-title">@Title</h5>
<button @onclick = "() => Close()" type = "button" class = "btn-close" data-dismiss = "modal" aria-label = "Close">
</button>
</div>
<div class = "modal-body">
@ChildContent
</div>
</div>
</div>
</div>
}
@code {
[Parameter]
public bool IsVisible { get; set; }
[Parameter]
public string Title { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public EventCallback<bool> IsVisibleChanged { get; set; }
public async Task Close()
{
IsVisible = false;
await IsVisibleChanged.InvokeAsync(IsVisible);
}
}
Какой дополнительный код мне нужен, чтобы закрыть его, когда я отключаю модальное окно? Я использую .NET 7 с boostrap 5 css. Кажется, я не могу изолировать фон, чтобы добавить событие щелчка, чтобы закрыть модальное окно.
Нет, это не работает
См. этот недавний ответ на Bootstrap Modals — stackoverflow.com/a/76105876/13065781





Добавьте @onclick = "Close" в div .modal и @onclick:stopPropagation в div .modal-dialog.
@using System.Threading.Tasks
@if (IsVisible)
{
<div class = "modal-backdrop fade show"></div>
<div id = "myModal" class = "modal show" style = "display: block;" @onclick = "Close">
<div class = "modal-dialog" role = "document" @onclick:stopPropagation>
<div class = "modal-content">
<div class = "modal-header">
<h5 class = "modal-title">@Title</h5>
<button @onclick = "Close" type = "button" class = "btn-close" data-dismiss = "modal" aria-label = "Close"></button>
</div>
<div class = "modal-body">
@ChildContent
</div>
</div>
</div>
</div>
}
@code {
[Parameter]
public bool IsVisible { get; set; }
[Parameter]
public string Title { get; set; }
[Parameter]
public RenderFragment ChildContent { get; set; }
[Parameter]
public EventCallback<bool> IsVisibleChanged { get; set; }
public async Task Close()
{
await IsVisibleChanged.InvokeAsync(false);
}
}
Также не рекомендуется делать IsVisible = false; внутри метода Close. Компонент blazor не должен устанавливать собственные параметры. Вместо этого позвольте родителю управлять параметром IsVisible, используя синтаксис @bind-.
<Modal @bind-IsVisible = "_isVisible" Title = "Modal">TEST</Modal>
@code {
private bool _isVisible = true;
}
@* which is equal to *@
<Modal IsVisible = "_isVisible" IsVisibleChanged = "OnIsVisibleChanged" Title = "Modal">TEST</Modal>
@code {
private bool _isVisible = true;
private void OnIsVisibleChanged(bool isVisible)
{
_isVisible = isVisible;
}
}
Вот простой модальный диалог, основанный на вашем коде, который имеет асинхронное поведение открытия/закрытия:
ModalDialog.razor
@if (_isVisible)
{
<div class = "modal-backdrop fade show"></div>
<div id = "myModal " class = "modal show" @onclick=this.CloseOnBackDropClickAsync style = "display: block">
<div class = "modal-dialog" role = "document">
<div class = "modal-content">
<div class = "modal-header">
<h5 class = "modal-title">@this.Title</h5>
<button @onclick=this.CloseAsync type = "button" class = "btn-close" data-dismiss = "modal" aria-label = "Close">
</button>
</div>
<div class = "modal-body">
@this.ChildContent
</div>
</div>
</div>
</div>
}
@code {
[Parameter] public string? Title { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public bool CloseOnBackdropClick { get; set; }
private bool _isVisible { get; set; }
private TaskCompletionSource _taskCompletionSource = new();
public Task OpenAsync()
{
_taskCompletionSource = new();
_isVisible = true;
StateHasChanged();
return _taskCompletionSource.Task;
}
public Task CloseAsync()
{
_isVisible = false;
StateHasChanged();
_taskCompletionSource.SetResult();
return _taskCompletionSource.Task;
}
public async Task CloseOnBackDropClickAsync()
{
if (CloseOnBackdropClick)
await CloseAsync();
}
}
И Index.razor
@page "/"
<PageTitle>Index</PageTitle>
<h1>Hello, world!</h1>
Welcome to your new app.
<ModalDialog Title = "Test Modal" @ref=_modalDialog>
<div class = "pb-3">Close me please</div>
<div class = "pb-3 text-end">
<button class = "btn btn-primary" @onclick=this.CloseDialogAsync>Close</button>
</div>
</ModalDialog>
<div class = "m-2 p-2">
<button class = "btn btn-dark" @onclick=OpenDialogAsync>Open Dialog</button>
</div>
@code {
private ModalDialog? _modalDialog;
private async Task OpenDialogAsync()
{
if (_modalDialog is not null)
await _modalDialog.OpenAsync();
//This code will not run after the modal has closed
}
private async Task CloseDialogAsync()
{
if (_modalDialog is not null)
await _modalDialog.CloseAsync();
}
}
Вы пытались добавить '@onclick = "() => Close()"' в div "modal-backdrop"?