通过OnInitializedAsync中设置的值刷新页面吗?

时间:2019-12-30 17:53:27

标签: asp.net asp.net-core blazor

我为Blazor的加载状态管理创建了一个非常简单的组件。 (.Net核心3.1,添加了部分类支持)

Shared / LoadContainer.razor

@if (State == LoadContainerState.Initial)
{
    @Initial
}
else if (State == LoadContainerState.Loading)
{
    @Loading
}
else if (State == LoadContainerState.Loaded)
{
    @Loaded
}
else if (State == LoadContainerState.Error)
{
    @ErrorContent
}

Shared / LoadContainer.razor.cs

using Microsoft.AspNetCore.Components;

namespace BlazorUI.Shared
{
    public enum LoadContainerState { Initial, Loading, Loaded, Error }

    public partial class LoadPageContainer
    {
        [Parameter]
        public LoadContainerState State { get; set; }

        [Parameter]
        public RenderFragment? Initial { get; set; }

        [Parameter]
        public RenderFragment? Loading { get; set; }

        [Parameter]
        public RenderFragment? Loaded { get; set; }

        [Parameter]
        public RenderFragment? ErrorContent { get; set; }
    }
}

它对于具有所有四个状态的应用程序都很好。

@using BlazorUI.Shared
<LoadPageContainer State="state">
    <Initial>
        <p>
            Please enter inputs.
        </p>
    </Initial>
    <Loading>
        <div class="lds-hourglass">Loading....</div>
    </Loading>
    <Loaded>
        Show the data
    </Loaded>
    <ErrorContent>
        <p style="color:red">@errorMsg</p>
    </ErrorContent>
</LoadPageContainer>

但是,如果我尝试加载数据并更改OnInitializedAsync()中的状态,它会保持初始状态吗?

LoadContainerState state = LoadContainerState.Initial;

protected override async Task OnInitializedAsync()
{
    state = LoadContainerState.Loading; // Doesn't switch to loading 
    var r = await ReadDataFromSlowDatabase();
    if (r.IsFailure) { error = r.Error; }
    else { vm = r.Value; error = null; }
    state = LoadContainerState.Loaded; // Doesn't switch to loaded
    // StateHasChanged(); // Not working
}

1 个答案:

答案 0 :(得分:0)

这是因为您将局部类命名为LoadPageContainer,文件名为LoadContainer.razor.cs和LoadContainer.razor。将类名更改为LoadContainer或将文件名更改为LoadPageContainer.razor.cs和LoadPageContainer.razor.cs

不带扩展名的文件名是组件名称和类型。

偶然地,在OnInitializedAsync中调用StateHasChanged方法是多余的,因为组件总是在此方法的执行流程结束时重新呈现。

为什么将Renderfragment属性定义为可为空?

LoadContainer.razor

@if (State == LoadPageContainerState.Initial)
{
    @Initial
}
else if (State == LoadPageContainerState.Loading)
{
    @Loading
}
else if (State == LoadPageContainerState.Loaded)
{
    @Loaded
}
else if (State == LoadPageContainerState.Error)
{
    @ErrorContent
}

LoadContainer.razor.cs

public enum LoadPageContainerState { Initial, Loading, Loaded, Error }

    public partial class LoadContainer
    {
        [Parameter]
        public LoadPageContainerState State { get; set; }

        [Parameter]
        public RenderFragment? Initial { get; set; }

        [Parameter]
        public RenderFragment? Loading { get; set; }

        [Parameter]
        public RenderFragment? Loaded { get; set; }

        [Parameter]
        public RenderFragment? ErrorContent { get; set; }
    }

用法(Index.razor)

     @page "/"

    <h1>Hello, world!</h1>

     Welcome to your new app.
    <LoadContainer State="state">
    <Initial>
        <p>
            Please enter inputs.
        </p>
    </Initial>
    <Loading>
        <div class="lds-hourglass">Loading....</div>
    </Loading>
    <Loaded>
        Show the data
    </Loaded>
    <ErrorContent>
        <p style="color:red">@errorMsg</p>
    </ErrorContent>
</LoadContainer>
@code{
    private string errorMsg = "ErrorRRRRRRRRRRRR";
    private LoadPageContainerState state;

    protected override async Task OnInitializedAsync()
    {
         // This is done so that you can see "Please enter inputs."
         await Task.Delay(2000);
    // After two second you'll see "Loading...."
    state = LoadPageContainerState.Loading;
    // must call StateHasChanged to perform a re-render
    StateHasChanged();
    // Delay for 5 seconds and then display "Show the data"
    await Task.Delay(5000);
    //if (r.IsFailure) { error = r.Error; }
    //else { vm = r.Value; error = null; }
    state = LoadPageContainerState.Loaded;
    }
}