Blazor组件行为OnAfterRenderAsync绑定

时间:2020-01-12 23:30:19

标签: blazor blazor-server-side

问题上下文

我有一些基本的绑定物component to wrap bootstrap modal

我有两个组件,它们包装了通过此模式组件公开的EditForm个组件:ConversionForm.razorConversionInputForm.razor

然后我通过一些简单的按钮(不使用引导程序模式数据绑定)在a page上使用这两个表单/模式组件。

问题

Add Conversion Input按钮使模态出现并正常工作。 Add Conversion按钮使模式出现,然后消失并离开模式背景。

问题排查

我在模态组件的OnAfterRenderAsync中添加了一个Console.WriteLine,以查看是否存在差异,我唯一注意到的是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]

第四行conversion-modal.OnAfterRenderAsync(True) [1]是我所怀疑的,就像该组件已重新初始化一样。不知道为什么或者这是否是问题的一部分。

感谢您的帮助。

更新

我将OnInitializedAsync控制台输出添加到Modal,并确认由于某种原因该框架重新实例化了该模式,现在再次确定这是造成此问题的原因,但是在我找到另一种故障排除途径之前,我一直怀疑。

添加转化输入(工作)输出

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]

添加转化(无效)输出

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 :(得分:0)

我发现围绕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);
}