Поведение компонентов Blazor OnAfterRenderAsyn c Binding - PullRequest
0 голосов
/ 13 января 2020

Контекст выпуска

У меня есть блазор для обертывания bootstrap модальный с некоторым базовым c связыванием.

У меня есть два компонента, которые обертывают EditForm компоненты, которые я открываю через этот модальный компонент: ConversionForm.razor и ConversionInputForm.razor .

Затем я использую эти два компонента формы / модала на странице с некоторыми простыми кнопками (не используя bootstrap модальное связывание данных).

Issue

* Кнопка 1019 *Add Conversion Input заставляет модал появляться и работать должным образом. Кнопка Add Conversion вызывает модальное появление, затем исчезает и оставляет модальный фон.

Устранение неполадок

Я добавил Console.WriteLine к OnAfterRenderAsyn c модального компонента, чтобы увидеть, есть ли разница, и единственное, что я заметил, это то, что conversion-modal.OnAfterRenderAsync(True) отображается после modal.ShowAsync метода, который исчезает.

Мне интересно, есть ли что-то в поведении привязки, которое вызывает такое поведение, так как я считаю, что firstRender = true должен происходить только один раз при начальной загрузке страница компонента.

Чтобы воспроизвести это поведение, создайте новое приложение Blazorserver dotnet new blazorserver и добавьте / измените файлы в this gist .

Вывод консоли для того, что работает:

conversion-modal.OnAfterRenderAsync(True) [1]
conversion-input-modal.OnAfterRenderAsync(True) [1]
conversion-input-modal.ShowAsync()
conversion-input-modal.OnAfterRenderAsync(False) [2]
conversion-modal.OnAfterRenderAsync(False) [2]
conversion-input-modal.OnAfterRenderAsync(False) [3]

Вывод на консоль для того, что сломано:

conversion-modal.OnAfterRenderAsync(True) [1]
conversion-input-modal.OnAfterRenderAsync(True) [1]
conversion-modal.ShowAsync()
conversion-modal.OnAfterRenderAsync(True) [1]  <<-------------
conversion-modal.OnAfterRenderAsync(False) [2]
conversion-input-modal.OnAfterRenderAsync(False) [2]

4-я строка conversion-modal.OnAfterRenderAsync(True) [1] - это то, что я подозреваю, как будто компонент был повторно инициализирован. Не уверен, почему или если это даже часть проблемы.

Помощь приветствуется.

Обновление

Я добавил консольный вывод OnInitializedAsyn c в модал и подтвердил, что модал по какой-то причине снова восстанавливает структуру фреймворком теперь уверен, что это вызывает проблему, но есть подозрение, пока я не найду другой способ устранения неполадок.

Добавить преобразование Ввод (РАБОТА) Выход

conversion-modal.OnInitializedAsync() [1]
conversion-input-modal.OnInitializedAsync() [1]
conversion-modal.OnInitializedAsync() [1]
conversion-input-modal.OnInitializedAsync() [1]
conversion-modal.OnAfterRenderAsync(True) [1]
conversion-input-modal.OnAfterRenderAsync(True) [1]
conversion-input-modal.ShowAsync()
conversion-input-modal.OnAfterRenderAsync(False) [2]
conversion-modal.OnAfterRenderAsync(False) [2]
conversion-input-modal.OnAfterRenderAsync(False) [3]

Добавить Выход преобразования (BROKEN)

conversion-modal.OnInitializedAsync() [1]
conversion-input-modal.OnInitializedAsync() [1]
conversion-modal.OnInitializedAsync() [1]
conversion-input-modal.OnInitializedAsync() [1]
conversion-modal.OnAfterRenderAsync(True) [1]
conversion-input-modal.OnAfterRenderAsync(True) [1]
conversion-modal.ShowAsync()
conversion-modal.OnInitializedAsync() [1]  <<-------------
conversion-modal.OnAfterRenderAsync(True) [1]  <<---------
conversion-modal.OnAfterRenderAsync(False) [2]
conversion-input-modal.OnAfterRenderAsync(False) [2]

1 Ответ

0 голосов
/ 13 января 2020

Лучший способ узнать, почему EditForm перестраивает дочерние элементы управления, это переместить EditForm ниже модального div. Таким образом, модальный div не удаляется / добавляется, только тело / нижний колонтитул модального, что нормально.

ModalEditForm.razor

@inherits ComponentBase
@inject IJSRuntime JSRuntime

<div class="modal" tabindex="-1" role="dialog" id="@Id" @attributes="Attributes">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">@Title</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <EditForm EditContext="@EditContext" Model="@Model" OnSubmit="@OnSubmit" OnInvalidSubmit="@OnInvalidSubmit" OnValidSubmit="@OnValidSubmit">
                @if (!(Validators is null))
                {
                    @Validators
                }

                <div class="modal-body">
                    @Body
                </div>
                @if (!(Footer is null))
                {
                    <div class="modal-footer">
                        @Footer
                    </div>
                }
            </EditForm>
        </div>
    </div>
</div>

@code {
    [Parameter]
    public string Id { get; set; } = "modal";

    [Parameter]
    public string Title { get; set; } = string.Empty;

    [Parameter] 
    public object Model { get; set; }

    [Parameter] 
    public EditContext EditContext { get; set; }

    [Parameter]
    public RenderFragment Validators { get; set; }

    [Parameter]
    public RenderFragment Body { get; set; }

    [Parameter]
    public RenderFragment Footer { get; set; }

    [Parameter] 
    public EventCallback<EditContext> OnSubmit { get; set; }

    [Parameter]
    public EventCallback<EditContext> OnValidSubmit { get; set; }

    [Parameter]
    public EventCallback<EditContext> OnInvalidSubmit { get; set; }

    [Parameter(CaptureUnmatchedValues = true)]
    public Dictionary<string, object> Attributes { get; set; } = new Dictionary<string, object>();

    public async Task ShowAsync()
        => await JSRuntime.InvokeVoidAsync("showModal", Id).ConfigureAwait(false);

    public async Task HideAsync()
        => await JSRuntime.InvokeVoidAsync("hideModal", Id).ConfigureAwait(false);
}
...