65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 Razor 的模板数据容器

starIconstarIconstarIconstarIconstarIcon

5.00/5 (10投票s)

2023 年 6 月 26 日

CPOL

2分钟阅读

viewsIcon

9579

与其在 Razor 组件中充斥着 `if (a == b)` 逻辑来显示项目,不如使用渲染片段来创建一个声明式组件。

引言

我一直在开发一个 Blazor 应用程序,并且我讨厌我的一个表单中存在一个又大又丑的 `if (a == b)` 语句来显示一些内容,`else` 显示一条消息,说明没有数据。这既难看,又不符合代码的模板化特性,所以我决定做些改变。

背景

这是一个简单的组件,包含三个变量,但它可以使代码看起来更整洁。消失的是像这样的代码

@if (_value == 0) {
  <p>There is no data</p>
} else {
  <div class="mb-8">
    <p>There is content here.</p>
  </div>
}

这段代码被(在我看来)更优雅的代码所取代

<DataContainer HasData="@(_value > 0)">
  <NoData>
    <p>There is no data</p>
  </NoData>
  <DataTemplate>
    <div class="mb-8">
      <p>There is content here</p>
    </div>
  </DataTemplate>
</DataContainer>

代码

这段代码的背后依赖于 Razor 让我们创建 `RenderFragments` 并使用它来创建我们自己的 `RenderTree` 的能力。代码就像创建三个参数一样简单,并像这样重写 `BuildRenderTree` 方法

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;

namespace Goldlight.ServiceVirtualisation.Components;

public class DataContainer : ComponentBase
{
  [Parameter] public bool HasData { get; set; }

  [Parameter] public RenderFragment DataTemplate { get; set; } = null!;

  [Parameter] public RenderFragment NoData { get; set; } = null!;

  protected override void BuildRenderTree(RenderTreeBuilder builder)
  {
    base.BuildRenderTree(builder);
    builder.AddContent(0, HasData ? DataTemplate : NoData);
  }
}

就是这样;这就是它的全部。创建了这个组件后,我发现我到处都在使用它。使用类似的概念构建一个显示和隐藏加载指示器的组件,并用内容替换它来管理加载组件,也很简单。

需要注意的是,我故意将组件设置为 `null!`,以表明即使它们最初定义为 `null`,在构建渲染树时,在使用它们之前它们肯定会有一个值。如果这些是可为空的属性,我可以在构建方法中添加检查,但由于我解决的问题是在不同条件下显示不同的数据,因此我不需要使渲染片段可为空。

我希望你喜欢这个技巧(没有代码下载,因为该技巧的代码只有十几行)。当你开始使用渲染片段时,你会发现各种各样的场景,你都想使用它们。

历史

  • 2023 年 6 月 26 日:初始版本
© . All rights reserved.