C# Blazor 显示微调器直到 foreach 循环完成

C# Blazor show spinner until foreach loop is finished

我有一个页面加载了 C# Blazor 中的项目列表。我试图找出一种微调器显示的方式,直到我的 foreach 循环迭代了所有列表项。这是我当前的代码:

            @foreach (var f in FlyersState.Value.Flyers)
            {
                @if (isLoading)
                {
                    <div class="spinner"></div>
                }
                else
                {
                    <tr>
                        <td class="clickable" @onclick="()=>OpenFlyerDetails(f)">
                            @f.DealNo
                            <a href="flyers/@(f.Id)" target="_blank"><i class="fas fa-external-link-alt"></i></a>
                        </td>
                        <td>@f.Range</td>
                        <td>@f.Id</td>
                        <td>
                            <a class=" float-right" href="" data-target="#flyerModal" data-toggle="modal" @onclick="(() => EditFlyer(f))">
                                <i class="fas fa-edit"></i>
                            </a>
                        </td>
                        <td>
                            <a class=" float-right" href="" data-target="#confirmModal" data-toggle="modal" @onclick="(() => ShowDeleteConfirmAtionDialog(f))">
                                <i class="far fa-trash-alt"></i>
                            </a>
                        </td>
                    </tr>
                }

            }

我的页面是这样初始化的:

    private Flyer selectedFlyer => FlyersState.Value.SelectedFlyer;
    private bool isLoading = true;

    Flyer flyer = new Flyer();

    protected override void OnInitialized()
    {

        base.OnInitialized();
        Dispatcher.Dispatch(new LoadFlyersAction());
        
    }

我 运行 遇到的问题是,当循环完成迭代我的 table 时,我不确定如何将 isLoading 变为 false。任何帮助将不胜感激。

我会这样做:

<div id="spinner" class="@(spinner-state)">

@foreach (var f in FlyersState.Value.Flyers)
            {
                @if (isLoading)
                {
                    <div class="spinner"></div>
                }
                else
                {
                    <tr>
                        <td class="clickable" @onclick="()=>OpenFlyerDetails(f)">
                            @f.DealNo
                            <a href="flyers/@(f.Id)" target="_blank"><i class="fas fa-external-link-alt"></i></a>
                        </td>
                        <td>@f.Range</td>
                        <td>@f.Id</td>
                        <td>
                            <a class=" float-right" href="" data-target="#flyerModal" data-toggle="modal" @onclick="(() => EditFlyer(f))">
                                <i class="fas fa-edit"></i>
                            </a>
                        </td>
                        <td>
                            <a class=" float-right" href="" data-target="#confirmModal" data-toggle="modal" @onclick="(() => ShowDeleteConfirmAtionDialog(f))">
                                <i class="far fa-trash-alt"></i>
                            </a>
                        </td>
                    </tr>
                }

            }

然后,在代码中

private string spinner-state = "show-spinner";

private Flyer selectedFlyer => FlyersState.Value.SelectedFlyer;
private bool isLoading = true;

Flyer flyer = new Flyer();

protected override void OnInitialized()
{

    base.OnInitialized();
    Dispatcher.ShutdownStarted += HideSpinner();
    Dispatcher.Dispatch(new LoadFlyersAction());
    
}

void HideSpinner(object sender, DispatcherShutdownEventArgs e)
{
     spinner-state = "hide-spinner";
}

工作 Blazor 演示

我创建了一个可用的 Blazor Fiddle,您可以将其用作指南 here。它模拟了一个很长的 运行 数据查询,并在 运行.

时显示一个加载图标

您的代码的主要问题是 if(isLoading) 条件位于构建 table 的循环内。这些需要通过将 if 语句移到循环外来反转。然后它将根据 isLoading.

的值正确显示加载图标或显示 table

所以不是这个逻辑:

loop over data {
  if loading 
     show icon 
  else 
     show table rows
  end
}

您希望它看起来像这样:

if (loading) 
   show icon
else 
    loop over data {
      show table rows
    }
end 

我建议的另一个更改是将数据加载到 OnInitializedAsync()OnAfterRenderAsync() 中。它们都是异步的,你可以“等待”你的数据而不需要额外的 Dispatcher。请注意,由于 pre-rendering,Blazor 服务器会调用初始化两次,如果您有较长的 运行 查询,您可能希望避免这种情况。然而,解决方案超出了问题的范围。