BlazorForms 低代码开源框架。第一部分:简介和种子项目
利用 C# 的类型安全优势,基于流程、表单和规则开发应用程序
本系列中所有 BlazorForms 文章
- BlazorForms 低代码开源框架。第一部分:简介和种子项目
- BlazorForms 低代码开源框架。第二部分:CrmLight 项目
- BlazorForms 低代码开源框架。第三部分:CrmLight 潜在客户看板
引言
当您需要为客户构建可用的原型,或者您的公司没有企业开发预算时,您别无选择,只能使用一些捷径和技巧,通常是低代码或无代码方法。在这篇文章中,我将介绍一种使用开源框架 BlazorForms 快速开发 UI 的方法。
快速开发不是这里唯一的优势,您还可以获得低维护和可预测的解决方案,之后可以通过自定义 UI 进行改进,并通过移动版本进行扩展。
BlazorForms 需要最少的 UI 开发知识,并有助于将数据实体呈现为单页应用程序。
为了最大限度地减少初始工作量,我们创建了种子项目,这些项目可在 GitHub 上找到,我已将最新种子项目版本 0.7.0 复制到我的博客存储库中。
从 GitHub 下载此博客文章代码
GitHub 上的 BlazorForms 项目
种子项目
BlazorForms 已作为 PRO CODERS PTY LTD 的内部项目开发了几年——一家总部位于澳大利亚、专注于高质量专家的咨询公司,现在我们决定将其开源分享给社区。
我们的框架将应用程序划分为 Flows(流程)、Forms(表单)和 Rules(规则)。这可以防止意大利面条式编码并减少运行时错误的数量,它还完全支持 Visual Studio 的智能感知。
为了演示每个组件的含义和外观,最好打开种子项目,让我们使用 Visual Studio 2022 来操作。
BlazorFormsSeed
该项目是使用 Visual Studio Blazor Server App 模板创建的,然后我们添加了 NuGet 包
BlazorForms
0.7.0BlazorForms.Rendering.MudBlazorUI
0.7.0
它还间接引用了 MudBlazor
6.1.5——一个为 Blazor 实现 Material Design 的开源框架。
导航菜单和布局也已更改为使用 MudBlazor
。
当您运行应用程序时,您可以看到动态生成的简单表单,它绑定到 Model,支持验证,并且还是一个 Flow 中的一个步骤,该 Flow 控制显示哪个 Form 以及在 Form 提交或关闭时执行哪些操作。
所有示例代码都位于 Flows\SampleFlow.cs 文件中,为简洁起见,我们将几个类放在一起。
模型
在文件底部,您可以找到一个 Model
类,这对于这种方法至关重要。Model
由 Flow 和 Form 中使用的属性组成,编译器会检查您是否在代码中使用了现有属性和正确的类型。
public class MyModel1 : IFlowModel
{
public virtual string? Message { get; set; }
public virtual string? Name { get; set; }
public virtual string? Logs { get; set; }
}
Flows
当定义 Flow 时,我们将 Model 作为 FluentFlowBase<>
泛型类型的模板参数进行引用,因此编译器知道 Model
类型并可以检查我们只使用了现有属性。
public class SampleFlow : FluentFlowBase<MyModel1>
{
public override void Define()
{
this
.Begin()
.NextForm(typeof(QuestionForm))
.If(() => Model.Name?.ToLower() == "admin")
.Next(() => Model.Logs = "Flow = 'SampleFlow'\r\nLast Form = 'QuestionForm'\r\nLast Action = 'Submit'")
.NextForm(typeof(AdminForm))
.Else()
.Next(() => { Model.Message = $"Welcome {Model.Name}"; })
.EndIf()
.NextForm(typeof(WellcomeForm))
.End();
}
}
Define 方法指定了一个步骤序列和条件分支,这些都共同控制了表示流程。
在 Sample Flow 中,我们定义了
- 最初显示
QuestionForm
,然后Flow
将等待用户输入 - 当按下 **Cancel** 按钮时,
Flow
将终止 - 当按下 **Submit** 按钮时,Flow 继续执行下一条语句 –
If
- 在
If
语句中,Flow 检查条件(输入的名称等于“admin
”) - 当输入“
admin
”时,将填充Logs
属性,并显示AdminForm
- 当输入其他内容时,将填充
Message
属性,并显示WellcomeForm
表单
在 Flow
中,我们使用了三个不同的 Form
,它们将 UI 控件附加到 Model
,该 Model
作为模板参数提供给泛型 class FormEditBase<>
。
public class QuestionForm : FormEditBase<MyModel1>
{
protected override void Define(FormEntityTypeBuilder<MyModel1> f)
{
f.DisplayName = "BlazorForms Sample";
f.Property(p => p.Name).Label("What is your name?").IsRequired();
f.Button("/", ButtonActionTypes.Close, "Cancel");
f.Button("/", ButtonActionTypes.Submit);
}
}
public class AdminForm : FormEditBase<MyModel1>
{
protected override void Define(FormEntityTypeBuilder<MyModel1> f)
{
f.Property(p => p.Logs).Control(ControlType.TextArea).IsReadOnly();
f.Button("/", ButtonActionTypes.Close);
}
}
public class WellcomeForm : FormEditBase<MyModel1>
{
protected override void Define(FormEntityTypeBuilder<MyModel1> f)
{
f.Property(p => p.Message).Control(ControlType.Header);
f.Button("/", ButtonActionTypes.Close);
}
}
在 QuestionForm
的 Define
方法中,我们有
- 渲染
Form
副标题“BlazorForms Sample
” - 对于
Model
属性Name
,渲染必需的输入控件 - 渲染“Cancel”按钮,按下时终止
Flow
- 渲染“Submit”按钮,用于提交
Form
并继续Flow
类似地,AdminForm
渲染一个只读文本区域,显示 Logs
属性,并且只有一个按钮,按下时终止 Flow
;WellcomeForm
渲染一个头部控件,显示 Message
属性和一个“Close”按钮。
您还记得,Logs
和 Message
属性的值是在 Flow 逻辑中填充的。
基本上,所有代码逻辑都包含在 Flows 和 Rules 中,而 Forms 只定义 Model
属性和应在 UI 中渲染的控件之间的绑定。
规则
Rules 可以附加到 Form
上的每个属性,并在值更改时触发。在 Rule
中,您可以放置可以触发验证错误、隐藏或显示控件、更改 Model
属性值等的逻辑。
基本的种子项目没有 Rule
的示例,但我将进行一些小的修改来演示它。
我修改了 QuestionForm
并添加了 NotWombatRule
。
public class QuestionForm : FormEditBase<MyModel1>
{
protected override void Define(FormEntityTypeBuilder<MyModel1> f)
{
f.DisplayName = "BlazorForms Sample";
f.Property(p => p.Name).Label("What is your name?")
.IsRequired().Rule(typeof(NotWombatRule));
f.Property(p => p.Message).Control(ControlType.Label).Label("").IsHidden();
f.Button("/", ButtonActionTypes.Close, "Cancel");
f.Button("/", ButtonActionTypes.Submit);
}
}
public class NotWombatRule : FlowRuleBase<MyModel1>
{
public override string RuleCode => "SFS-1";
public override void Execute(MyModel1 model)
{
if (model.Name?.ToLower() == "wombat")
{
model.Message = "really?";
Result.Fields[SingleField(m => m.Message)].Visible= true;
}
else
{
model.Message = "";
Result.Fields[SingleField(m => m.Message)].Visible = false;
}
}
}
如您所见,QuestionForm
现在有一个隐藏的 Message
属性控件,并且 NotWombatRule
已附加到 Name
属性。当用户在 Name
字段中输入“wombat
”并按 **Tab** 键将焦点移至下一个控件时,Rule
将被触发,它将检查输入的 Name
,并且 Message
将被显示。
Rules 也接受 Model 模板参数并支持类型安全,如果您使用不存在的 Model 属性或类型不匹配,您将看到编译错误。
Blazor 页面
在定义了 Flow、Forms 和 Rules 之后,我们就可以在 Blazor 页面上使用它们了。该项目中的 Pages 文件夹包含 Sample.razor 文件。
@page "/sample"
<FlowEditForm FlowName="@typeof(BlazorFormsSeed.Flows.SampleFlow).FullName"
Options="Options" NavigationSuccess="/" />
@code {
EditFormOptions Options = new EditFormOptions
{ MudBlazorProvidersDefined = true, Variant=Variant.Filled };
}
我们将 FlowEditForm
razor 组件放在这里,并提供了一些参数:Flow 的类型、Options 以及 Flow 完成后要导航到的位置。
当用户导航到“/sample”页面时,BlazorForms
框架会创建一个 SampleFlow
的实例并开始逐步执行它。当遇到第一个 Form 时,它会渲染 Form 数据并等待用户输入。当输入数据并提交 Form 后,Flow 执行将继续直到结束。
Program.cs 和 _Hosts.cshtml
我应该提到的最后一件事是如何在您的 Blazor 应用程序中注册 BlazorForms
框架。这在 Program.cs 文件中完成。
// BlazorForms
builder.Services.AddServerSideBlazorForms();
builder.Services.AddBlazorFormsMudBlazorUI();
builder.Services.AddBlazorFormsServerModelAssemblyTypes(typeof(SampleFlow));
var app = builder.Build();
// BlazorForms
app.BlazorFormsRun();
CSS 和 JavaScript 文件的引用应添加到 _Hosts.cshtml 文件中。
<!-- MudBlazor -->
<link href="https://fonts.googleapis.com/css?
family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
摘要
在这篇文章中,我介绍了 BlazorForms 框架——一个开源项目,它简化了 Blazor UI 开发,并允许创建简单且易于维护的 C# 代码,这对于低预算项目和原型制作非常有益。其主要思想是将不依赖于 UI 且可进行单元测试的逻辑放在 Flows 和 Rules 中;而 Forms 只包含 Model 和 UI 控件之间的绑定。
这篇文章是对 BlazorForms 的简要介绍,我没有涵盖不同类型的 Flows、如何在会话之间存储 Flow 状态、如何在 JSON 中定义 Flows 和 Forms(而不是 C#)以及许多其他功能。所有这些都将在我之后的博客中介绍。
PRO CODERS 团队认为,BlazorForms 框架甚至可以用于大型项目,其中需要以最少的精力和可接受的质量来实现和维护数百个表单。它应该是自定义 UI 实现的一个很好的替代方案,在自定义 UI 实现中,每个页面/表单都需要巨大的开发和测试工作量,并且随着时间的推移添加修改时质量会下降。
下一篇 – CrmLightDemoApp 种子项目
更复杂的场景将在稍后介绍,我们将开始查看 CrmLightDemoApp
种子项目。
它有几个与实现 CRUD 操作的 Repositories 相连接的 Flows,现在,我将展示一些截图。
您可以在我的 GitHub 上找到完整的解决方案代码,文件夹为 Story-08-BlazorForms-Intro-Seeds。
感谢您的阅读,请记住,如果您在实施过程中需要任何帮助,可以随时与我们联系。
https://procoders.com.au/contact-us/
历史
- 2023 年 1 月 9 日:初始版本