Bootstrap Blazor 实战动态表单组件
1.新建工程
源码
新建工程b18ValidateForm,使用 nuget.org 进行 BootstrapBlazor 组件安装, Chart 库,字体. 将项目添加到解决方案中
dotnet new blazorserver -o b18ValidateForm
dotnet add b06chart package BootstrapBlazor
dotnet add b06chart package BootstrapBlazor.FontAwesome
dotnet sln add b18ValidateForm/b18ValidateForm.csproj
2.样式表和Javascript 引用
增加主题样式表到 Pages/_Layout.cshtml
文件中
删除 <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
并在下面添加三行
<link href="_content/BootstrapBlazor.FontAwesome/css/font-awesome.min.css" rel="stylesheet" />
<link href="_content/BootstrapBlazor/css/bootstrap.blazor.bundle.min.css" rel="stylesheet" />
添加 Javascript 引用到 Pages/_Layout.cshtml
文件中
在 <script src="_framework/blazor.server.js"></script>
之前添加
<script src="_content/BootstrapBlazor/js/bootstrap.blazor.bundle.min.js" asp-append-version="true"></script>
3.添加增加命名空间引用到 _Imports.razor
文件中
@using BootstrapBlazor.Components
4.增加 BootstrapBlazorRoot 组件到 App.razor 文件中
<BootstrapBlazorRoot><Router AppAssembly="@typeof(App).Assembly">...</Router>
</BootstrapBlazorRoot>
5.添加BootstrapBlazor服务到 Program.cs
文件中
在 builder.Services.AddSingleton<WeatherForecastService>();
后加入
builder.Services.AddBootstrapBlazor();
6.添加EditorForm测试代码
Index.razor
<EditorForm Model="@Model"><FieldItems><EditorItem @bind-Field="@context.Name" /><EditorItem @bind-Field="@context.Education" /><EditorItem @bind-Field="@context.Complete" /></FieldItems><Buttons><Button Icon="fa-solid fa-floppy-disk" Text="提交" /></Buttons>
</EditorForm>
Index.razor.cs
using BootstrapBlazor.Components;
using Microsoft.Extensions.Localization;
using System.Collections.Concurrent;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;namespace b18ValidateForm.Pages;public sealed partial class Index
{[NotNull]private Foo? Model { get; set; }/// <summary>/// <inheritdoc/>/// </summary>protected override void OnInitialized(){Model = new Foo(){Name = "",Count = 1,Address = "TestAddress",DateTime = new DateTime(1997, 12, 05),Education = EnumEducation.Middle};}}
Demo示例数据
/// <summary>
/// Demo示例数据
/// Demo sample data
/// </summary>
public class Foo
{// 列头信息支持 Display DisplayName 两种标签/// <summary>////// </summary>[Display(Name = "主键")][AutoGenerateColumn(Ignore = true)]public int Id { get; set; }/// <summary>////// </summary>[Required(ErrorMessage = "{0}不能为空")][AutoGenerateColumn(Order = 10, Filterable = true, Searchable = true)][Display(Name = "姓名")]public string? Name { get; set; }/// <summary>////// </summary>[AutoGenerateColumn(Order = 1, FormatString = "yyyy-MM-dd", Width = 180)][Display(Name = "日期")]public DateTime? DateTime { get; set; }/// <summary>////// </summary>[Display(Name = "地址")][Required(ErrorMessage = "{0}不能为空")][AutoGenerateColumn(Order = 20, Filterable = true, Searchable = true)]public string? Address { get; set; }/// <summary>////// </summary>[Display(Name = "数量")][Required][AutoGenerateColumn(Order = 40, Sortable = true)]public int Count { get; set; }/// <summary>////// </summary>[Display(Name = "是/否")][AutoGenerateColumn(Order = 50)]public bool Complete { get; set; }/// <summary>////// </summary>[Required(ErrorMessage = "请选择学历")][Display(Name = "学历")][AutoGenerateColumn(Order = 60)]public EnumEducation? Education { get; set; }/// <summary>////// </summary>[Required(ErrorMessage = "请选择一种{0}")][Display(Name = "爱好")][AutoGenerateColumn(Order = 70, Editable = false)]public IEnumerable<string> Hobby { get; set; } = new List<string>();#region Static methods/// <summary>/// /// </summary>protected static readonly Random Random = new();/// <summary>/// 生成Foo类,随机数据/// Generate Foo class, random data/// </summary>/// <param name="localizer"></param>/// <returns></returns>public static Foo Generate(IStringLocalizer<Foo> localizer) => new(){Id = 1,Name = localizer["Foo.Name", "1000"],DateTime = System.DateTime.Now,Address = localizer["Foo.Address", $"{Random.Next(1000, 2000)}"],Count = Random.Next(1, 100),Complete = Random.Next(1, 100) > 50,Education = Random.Next(1, 100) > 50 ? EnumEducation.Primary : EnumEducation.Middle};/// <summary>/// 生成 Foo 类,随机数据/// Generate Foo class, random data/// </summary>/// <returns>返回一个Foo类的List,Return a List of Foo class</returns>public static List<Foo> GenerateFoo(int count = 80) => Enumerable.Range(1, count).Select(i => new Foo(){Id = i,Name = "Foo.Name"+ $"{i:d4}",DateTime = System.DateTime.Now.AddDays(i - 1),Address = "Foo.Address"+$"{Random.Next(1000, 2000)}",Count = Random.Next(1, 100),Complete = Random.Next(1, 100) > 50,Education = Random.Next(1, 100) > 50 ? EnumEducation.Primary : EnumEducation.Middle}).ToList();/// <summary>/// 通过 Count 获得颜色/// </summary>/// <param name="count"></param>/// <returns></returns>public static Color GetProgressColor(int count) => count switch{>= 0 and < 10 => Color.Secondary,>= 10 and < 20 => Color.Danger,>= 20 and < 40 => Color.Warning,>= 40 and < 50 => Color.Info,>= 50 and < 70 => Color.Primary,_ => Color.Success};/// <summary>/// 通过 Id 获取 Title/// </summary>/// <returns></returns>private static string GetTitle() => Random.Next(1, 80) switch{>= 1 and < 10 => "Clerk",>= 10 and < 50 => "Engineer",>= 50 and < 60 => "Manager",>= 60 and < 70 => "Chief",_ => "General Manager"};/// <summary>/// /// </summary>/// <param name="id"></param>/// <returns></returns>public static string GetTitle(int id) => Cache.GetOrAdd(id, key => GetTitle());/// <summary>/// /// </summary>/// <returns></returns>public static Func<IEnumerable<Foo>, string, SortOrder, IEnumerable<Foo>> GetNameSortFunc() => Utility.GetSortFunc<Foo>();private static ConcurrentDictionary<int, string> Cache { get; } = new();#endregion
}/// <summary>
///
/// </summary>
public enum EnumEducation
{/// <summary>////// </summary>[Display(Name = "小学")]Primary,/// <summary>////// </summary>[Display(Name = "中学")]Middle
}
7.运行
8.新需求: 在点击[是/否]的时候,动态控制姓名和地址栏只读
尝试把代码改为
<EditorForm Model="@Model"><FieldItems>@*<InputDIY Context="@context" />*@@if (context.Complete){<EditorItem @bind-Field="@context.Name" Readonly="@context.Complete" /><EditorItem @bind-Field="@context.Education" Readonly="@context.Complete" />}<EditorItem @bind-Field="@context.DateTime" Readonly="true" /><EditorItem @bind-Field="@context.Complete" /></FieldItems><Buttons><Button Icon="fa-solid fa-floppy-disk" Text="提交" /></Buttons>
</EditorForm>
运行之, 并没有达到预期. 无论怎么改变[是/否]检查框,姓名和地址栏都是可写的,因为渲染机制问题,所以要改一下思路.
正确方法是把逻辑包成一个组件,组件里面就可以局部刷新达到预期效果
9.新建组件 InputDIY.razor
<Row><BootstrapInput @bind-Value="@Context!.Name" IsDisabled="@Context!.Complete" ShowLabel="true" /><BootstrapInput @bind-Value="@Context!.Education" IsDisabled="@Context!.Complete" ShowLabel="true" /> </Row><br />@code{[Parameter] public Foo? Context { get; set; }}
Index.razor代码改为
<EditorForm Model="@Model"><FieldItems><InputDIY Context="@context" /><EditorItem @bind-Field="@context.Name" Editable="@context.Complete" /><EditorItem @bind-Field="@context.Education" Editable="@context.Complete" /><EditorItem @bind-Field="@context.DateTime" Readonly="true" /><EditorItem @bind-Field="@context.Complete" /></FieldItems><Buttons><Button Icon="fa-solid fa-floppy-disk" Text="提交" /></Buttons>
</EditorForm>
注:如果不加入以下写法,会照成InputDIY里面渲染一次Name列,FieldItems又渲染一次Name列.这是MS的内部机制一个小坑,暂时没有办法避开.
<EditorItem @bind-Field="@context.Name" Editable="@context.Complete" />
10.运行效果
11.数据验证 ValidateForm
<ValidateForm Model="@Model"><EditorForm TModel="Foo"><FieldItems><InputDIY Context="@context" /><EditorItem @bind-Field="@context.Name" Editable="@context.Complete" /><EditorItem @bind-Field="@context.Education" Editable="@context.Complete" /><EditorItem @bind-Field="@context.DateTime" Readonly="true" /><EditorItem @bind-Field="@context.Complete" /></FieldItems><Buttons><Button ButtonType="ButtonType.Submit" Icon="fa-solid fa-floppy-disk" Text='提交' /></Buttons></EditorForm>
</ValidateForm>
12.DEMO源码
相关文章:

Bootstrap Blazor 实战动态表单组件
1.新建工程 源码 新建工程b18ValidateForm,使用 nuget.org 进行 BootstrapBlazor 组件安装, Chart 库,字体. 将项目添加到解决方案中 dotnet new blazorserver -o b18ValidateForm dotnet add b06chart package BootstrapBlazor dotnet add b06chart package BootstrapBlazo…...

Elasticsearch 集成---Spark Streaming 框架集成
一.Spark Streaming 框架介绍 Spark Streaming 是 Spark core API 的扩展,支持实时数据流的处理,并且具有可扩展, 高吞吐量,容错的特点。 数据可以从许多来源获取,如 Kafka , Flume , Kin…...
Kotlin 中的 协程 基础篇
一、什么叫协程 协程可以称为轻量级线程,线程代码块; 二、GlobalScope 协程 CoroutineScope (协程作用域) 的上下文中通过 launch、async 等构造器来启动。GlobalScope ,即全局作用域内启动了一个新的协程,这意味这该协程的生命周期只受整…...
SQL事务
事务的概念: 事务是在数据库上按照一定的逻辑顺序执行的任务序列,既可以由用户手动执行,也可以由某种数据库程序自动执行。事务就是一些SQL语句组(每条单独的SQL语句也算一个事务),其中事务中的SQL…...
关于flutter中 initState() 与 setState() 用法
initState()函数是在组件渲染之前执行的。在Flutter中,initState()是StatefulWidget的生命周期方法之一,在调用build()方法之前被调用。当创建一个StatefulWidget并将其添加到组件树中时,Flutter会实例化该组件的状态对象,并在调用…...
智能电话机器人是如何自主学习的
电话机器人主要通过语音识别和针对语意的理解识别客户所说的内容,针对性的回答问题,为企业高效筛选意向客户。除了电话机器人语音识别之外,电话机器人能够自主学习,不断完善产品知识及话术等,是它智能的另一种体现。那…...

【Rust】Rust学习 第十八章模式用来匹配值的结构
模式是 Rust 中特殊的语法,它用来匹配类型中的结构,无论类型是简单还是复杂。结合使用模式和 match 表达式以及其他结构可以提供更多对程序控制流的支配权。模式由如下一些内容组合而成: 字面值解构的数组、枚举、结构体或者元组变量通配符占…...
我的学习笔记:数据处理
数据清洗 对数据进行处理和加工,以使其适合分析和建模。数据清洗包括去除重复数据、填补缺失值、处理异常值和转换数据格式等操作,以提高数据的可靠性和准确性,避免数据分析时出现偏差,提高决策的准确性。 数据去重:通…...

GB28181国标平台测试软件NTV-GBC(包含服务器和模拟客户端)
GB28181国标平台测试软件NTV-GBC用于对GB28181国标平台进行测试(测试用例需要服务器软件,服务器软件可以是任何标准的国标平台,我们测试使用的是NTV-GBS),软件实现了设备注册、注销、目录查询,消息订阅、INVITE&#x…...
云原生:重塑企业的技术疆界
云原生技术正在重新塑造我们对软件开发、部署和运维的理解。这些技术带来了灵活性、可扩展性以及在复杂环境中保证稳定性的可能性,这些都是企业在云原生场景中比较关注的问题。本文将主要聚焦于云原生场景,探讨其影响和作用。 云原生的定义 云原生计算基…...

华为星闪,一项将 “ 更稳 WiFi ” 和 “ 更好蓝牙 ” 融合起来的通信标准
兼顾多用途和专业化的 AI 大模型、移除安卓代码的 HarmonyOS NEXT 、给折叠屏应用提供适配方向的《 折叠屏/平板应用体验评估标准 》。。。 不过除了这些比较贴近我们普通用户,容易讲清楚的东西,华为还官宣了一个大家可能没注意的黑科技: 星…...

IDEA创建Mybatis格式XML文件
设置位置:File | Settings | Editor | File and Code Templates 选择Files,点击号 Name中输入xml模板名(名称自行决定),后缀名extension输入xml(固定) 内容处输入Mybatis的xml文件模板内容&…...

二叉树中的最大路径和-递归
路径 被定义为一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点,且不一定经过根节点。 路径和 是路径中各节点值的总和。 给你一个二叉树的根节点 root…...
Python if-else 速记
文章目录 在 Python 中使用三元运算符作为 if-else 速记总结 编程中经常使用速记符号来简化我们的工作。 速记符号是一种可以更简洁、更省时省力地完成工作的方法。 本文将讨论 Python 中使用的速记符号作为 if-else 语句的快捷方式。 在 Python 中使用三元运算符作为 if-else…...
Python使用内置的json模块来处理JSON数据
目录 1、解释说明: 2、使用示例: 3、注意事项: 1、解释说明: 在Python中,我们可以使用内置的json模块来处理JSON数据。这个模块提供了四个主要的函数:dumps、loads、dump、load。 - dumps:将…...

亿赛通电子文档安全管理系统 RCE漏洞
亿赛通电子文档安全管理系统 RCE漏洞 一、 产品简介二、 漏洞概述三、 复现环境四、 漏洞复现小龙POC检测: 五、 修复建议 免责声明:请勿利用文章内的相关技术从事非法测试,由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失…...
信息安全面试题合集
0x00 前言 本篇会记录一些可能会遇到的面试题,持续更新 0x01 Web SQL注入 sql注入常见的闭合方式有哪些?Mysql5.0上下sql注入有什么区别?SQL注入空格被过滤,有什么绕过方式?过滤了逗号,有什么绕过方式&…...

vue 简单实验 自定义组件 传参数 props
1.代码 <script src"https://unpkg.com/vuenext" rel"external nofollow" ></script> <div id"todo-list-app"><todo-item v-bind:todo"todo1"></todo-item> </div> <script> const ListR…...

目标检测笔记(十一):如何结合特定区域进行目标检测(基于OpenCV的人脸检测实例)
文章目录 背景代码结果 背景 由于我们在做项目的时候可能会涉及到某个指定区域进行目标检测或者人脸识别等任务,所以这篇博客是为了探究如何在传统目标检测的基础上来结合特定区域进行检测,以OpenCV自带的包为例。 一般来说有两种方式实现区域指定&…...

PID直观感受简述
0、仿真控制框图 1、增加p的作用(增加响应)P 2、增加I的作用(消除稳差)PI 3、增加D的作用(抑制波动)PID 加入对噪声很敏 4、综合比对...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...

一些实用的chrome扩展0x01
简介 浏览器扩展程序有助于自动化任务、查找隐藏的漏洞、隐藏自身痕迹。以下列出了一些必备扩展程序,无论是测试应用程序、搜寻漏洞还是收集情报,它们都能提升工作流程。 FoxyProxy 代理管理工具,此扩展简化了使用代理(如 Burp…...
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法
用神经网络读懂你的“心情”:揭秘情绪识别系统背后的AI魔法 大家好,我是Echo_Wish。最近刷短视频、看直播,有没有发现,越来越多的应用都开始“懂你”了——它们能感知你的情绪,推荐更合适的内容,甚至帮客服识别用户情绪,提升服务体验。这背后,神经网络在悄悄发力,撑起…...
从实验室到产业:IndexTTS 在六大核心场景的落地实践
一、内容创作:重构数字内容生产范式 在短视频创作领域,IndexTTS 的语音克隆技术彻底改变了配音流程。B 站 UP 主通过 5 秒参考音频即可克隆出郭老师音色,生成的 “各位吴彦祖们大家好” 语音相似度达 97%,单条视频播放量突破百万…...
LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考
目录 lua脚本 记录流水 记录流水的作用 流水什么时候删除 我们在做库存扣减的时候,显示基于Lua脚本和Redis实现的预扣减 这样可以在秒杀扣减的时候保证操作的原子性和高效性 lua脚本 // ... 已有代码 ...Overridepublic InventoryResponse decrease(Inventor…...