Как закрыть модальное окно Blazor Webassembly

У меня есть компонент 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. Кажется, я не могу изолировать фон, чтобы добавить событие щелчка, чтобы закрыть модальное окно.

Вы пытались добавить '@onclick = "() => Close()"' в div "modal-backdrop"?

Axekan 26.04.2023 18:44

Нет, это не работает

wolfman928 26.04.2023 18:55

См. этот недавний ответ на Bootstrap Modals — stackoverflow.com/a/76105876/13065781

MrC aka Shaun Curtis 26.04.2023 20:51
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
66
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Добавьте @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();
    }
}

Другие вопросы по теме