尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
ant-design-blazor 使用 ModalService 创建 Confirm 模板对话框:自定义模板组件与返回值回调实战
UI组件前端【免费下载链接】ant-design-blazorA rich set of enterprise-class UI components based on Ant Design and Blazor.项目地址https://gitcode.com/gh_mirrors/an/ant-design-blazor点击查看免费下载本文以 ant-design-blazor 仓库中的 Modal_service_for_confirm 示例 为骨架系统讲解如何通过ModalService以编程方式创建 Confirm 确认框既可以直接传入RenderFragment作为内容也可以注入一个继承自FeedbackComponent的自定义模板组件并在用户点击 OK 时拦截关闭流程、校验输入、回传结果。读完本文你将掌握 Confirm 的两种创建方式、FeedbackComponent泛型参数含义、OnFeedbackOkAsync取消关闭机制、ConfirmRef/ModalRef动态更新配置以及模板组件销毁时机的控制。一、场景与前置准备在 ant-design-blazor 中Confirm 对话框既可以直接在 Razor 标记中使用Confirm组件官方在 Confirm.razor.cs 中明确注释DO NOT use Confirm Directly不推荐直接使用更推荐通过服务注入的方式动态创建。当业务需要在任意代码位置比如事件处理器、服务层弹出一个确认框并且确认框内部带有自定义表单、校验逻辑甚至把校验结果回传给调用方时ModalService 自定义模板组件就是标准解法。本示例由两个文件组成文件作用Modal_service_for_confirm.razor演示页面注入ModalService提供 Use Component 与 Use Template 两个按钮分别演示两种创建方式ConfirmTemplateDemo.razor自定义模板组件继承FeedbackComponentstring, string内部含一个输入框点击 OK 时校验输入是否与初始值一致使用前需要在组件中注入服务inject ModalService ModalService同时确保应用中存在 Confirm 容器。ModalService通过内部事件OnConfirmOpenEvent/OnConfirmCloseEvent/OnConfirmCloseAllEvent/OnConfirmUpdateEvent驱动渲染这些事件在 ComfirmContainer.razor.cs 的OnInitialized中注册并通过NavigationManager.LocationChanged在路由切换时清理所有 Confirm 实例。因此在宿主页面或布局中放置ComfirmContainer /或等效的确认容器是对话框能正常弹出的前提。二、方式一通过 RenderFragment 直接定义内容Use Component示例中的OpenComponent演示了最简单的方式——把一段 Razor 内容RenderFragment直接作为ConfirmOptions.Content传入private ConfirmRef _confirmRef; private async Task OpenComponent() { RenderFragment content divvalue: value br /Button OnClickCloseModalclose/Button/div; var options new ConfirmOptionsstring() { Title Confirm, Width 350, Content content, OnOpen () { Console.WriteLine(Open Confirm); return Task.CompletedTask; }, OnClose () { Console.WriteLine(Close Confirm); return Task.CompletedTask; }, OnCancel (result) { Console.WriteLine($OnCancel:{result}); return Task.CompletedTask; }, OnOk (result) { Console.WriteLine($OnOk:{result}); return Task.CompletedTask; } }; await ModalService.CreateConfirmAsync(options); } private async Task CloseModal() { if (_confirmRef ! null) { await _confirmRef.CloseAsync(); } }几个要点ConfirmOptionsstring是带返回值TResult的配置类其OnOk/OnCancel回调签名是FuncTResult?, Task会收到用户点击确认框后回传的结果值定义见 ConfirmOptions.cs。OnOpen/OnClose在对话框打开/关闭时触发OnOk/OnCancel仅在通过ModalService创建的 Confirm 中触发源码注释明确这一点ConfirmOptions.cs。RenderFragment content内部的Button OnClickCloseModalclose/Button演示了在内容里通过按钮主动关闭保存CreateConfirmAsync返回的ConfirmRef调用其CloseAsync()。ModalService.CreateConfirmAsync(options)会挂起等待直到确认框关闭查看 ModalServiceForConfirm.cs 可知它在创建ConfirmRef并初始化TaskCompletionSourceConfirmResult后await confirmRef.TaskCompletionSource.Task等待结果。三、方式二注入自定义模板组件Use Template当确认框内需要复杂表单、独立校验逻辑甚至要把输入值回传给调用方时应该把内容抽取成一个继承FeedbackComponent的模板组件。示例中通过以下调用把ConfirmTemplateDemo组件注入到确认框里private async Task OpenTemplate() { var options new ConfirmOptions() { Title Component, }; await ModalService.CreateConfirmAsyncConfirmTemplateDemo, string, string(options, value); }这里的三个泛型参数对应ConfirmTemplateDemo模板组件类型必须继承FeedbackComponentTComponentOptions, TResult第一个stringTComponentOptions即传给模板组件的配置通过Options参数接收第二个stringTResult即点击 OK 后回传给调用方的结果类型。模板组件本身ConfirmTemplateDemo.razorinherits FeedbackComponentstring, string div TextPlease input config/Text value: Input bind-Valuevalue Placeholderconfig / /div code{ string config; string value; protected override void OnInitialized() { config this.Options; base.OnInitialized(); } public override async Task OnFeedbackOkAsync(ModalClosingEventArgs args) { if (FeedbackRef is ConfirmRef confirmRef) { confirmRef.Config.OkButtonProps.Loading true; await confirmRef.UpdateConfigAsync(); } else if (FeedbackRef is ModalRef modalRef) { modalRef.Config.ConfirmLoading true; await modalRef.UpdateConfigAsync(); } await Task.Delay(1000); // only the inputs value equals the initialized value, the OK button will close the confirm dialog box if (value ! config) args.Cancel true; else // method 1(not recommended): await (FeedbackRef as ConfirmRefstring)!.OkAsync(value); // method 2: await (FeedbackRef as IOkCancelRefstring)!.OkAsync(value); await base.OkCancelRefWithResult!.OnOk(value); await base.OnFeedbackOkAsync(args); } /// summary /// If you want bDispose/b to take effect every time it is closed in Modal, which created by ModalService, /// set bModalOptions.DestroyOnClose true/b /// /summary /// param namedisposing/param protected override void Dispose(bool disposing) { Console.WriteLine(Dispose); base.Dispose(disposing); } }3.1 FeedbackComponent 的两个泛型参数FeedbackComponentTComponentOptions, TResult定义于 FeedbackComponent.cs它同时实现了IModalTemplate并派生自TemplateComponentBaseTComponentOptions见 TemplateComponentBase.cs因此模板组件自动拥有两个关键成员Options类型TComponentOptions外部传入的配置。示例中OnInitialized里执行config this.Options即把创建时传入的valueblazor取出来作为校验基准FeedbackRef类型IFeedbackRef指向创建本次对话框的引用对象ConfirmRef或ModalRef赋值时会自动把当前组件挂到FeedbackRef.ModalTemplate上见 FeedbackComponent.cs。ModalService创建模板 Confirm 时内部通过CreateChildRenderFragment生成渲染片段把FeedbackRef和Options作为参数传给模板组件ModalServiceForConfirm.csprivate RenderFragment CreateChildRenderFragmentTComponent, TComponentOptions(FeedbackRefBase feedbackRef, TComponentOptions componentOptions) where TComponent : IComponent { return (builder) { builder.OpenComponentTComponent(0); builder.AddAttribute(1, FeedbackRef, feedbackRef); builder.AddAttribute(2, Options, componentOptions); builder.CloseComponent(); }; }这解释了为什么模板组件里能直接使用FeedbackRef与Options它们是在运行时由框架注入的属性而不是页面编写者手工赋值的。3.2 OnFeedbackOkAsync拦截 OK 关闭流程当用户点击 Confirm 的 OK 按钮时底层 Confirm.razor.cs 的HandleOk会依次执行构造ModalClosingEventArgs默认Cancel false调用modalTemplate.OnFeedbackOkAsync(args)—— 也就是模板组件重写的方法若args.Cancel false且存在Config.OnOk则先置 OK 按钮Loading true再触发回调若args.Cancel false执行Close()并通过TaskCompletionSource.TrySetResult(confirmResult)通知等待方若被取消则把 Loading 复位并保持对话框打开。因此在OnFeedbackOkAsync中把args.Cancel true就能阻止对话框关闭。示例利用这一点实现了输入值校验只有输入与初始化值一致确认框才允许关闭不一致时保持打开并让用户重试。ModalClosingEventArgsModalClosingEventArgs.cs提供两个成员Cancel置true表示取消关闭默认falseReject()等价于Cancel true的便捷方法。3.3 带返回值的结果回传IOkCancelRefTResult示例中值校验通过后的回传// method 1(not recommended): await (FeedbackRef as ConfirmRefstring)!.OkAsync(value); // method 2: await (FeedbackRef as IOkCancelRefstring)!.OkAsync(value); await base.OkCancelRefWithResult!.OnOk(value);两种方法背后是同一个对象ConfirmRefTResult实现了IOkCancelRefTResult接口ConfirmRef.cs接口定义于 IOkCancelRef.cspublic interface IOkCancelRefTResult : IFeedbackRef { public FuncTResult, Task OnCancel { get; set; } public FuncTResult, Task OnOk { get; set; } public Task OkAsync(TResult result); public Task CancelAsync(TResult result); }ConfirmRefTResult.OkAsync(result)会调用OnOk?.Invoke(result)从而把模板内的value传回给ModalService.CreateConfirmAsyncConfirmTemplateDemo, string, string(...)创建时传入的ConfirmOptionsstring.OnOk回调在 ModalServiceForConfirm.cs 中会把ConfirmOptionsTResult的OnOpen/OnClose/OnOk/OnCancel赋值到confirmRef上。推荐优先使用base.OkCancelRefWithResult!.OnOk(value)FeedbackComponentTComponentOptions, TResult暴露的OkCancelRefWithResult属性FeedbackComponent.cs会安全地把FeedbackRef转型为IOkCancelRefTResult代码更简洁也避免了直接依赖具体的ConfirmRefTResult类型。第一种as ConfirmRefstring强转写法被注释标注为 not recommended。3.4 兼容 ConfirmRef 与 ModalRef动态更新按钮 LoadingOnFeedbackOkAsync开头的一段同时处理了两种引用类型if (FeedbackRef is ConfirmRef confirmRef) { confirmRef.Config.OkButtonProps.Loading true; await confirmRef.UpdateConfigAsync(); } else if (FeedbackRef is ModalRef modalRef) { modalRef.Config.ConfirmLoading true; await modalRef.UpdateConfigAsync(); }若当前对话框是 ConfirmConfirmRef通过Config.OkButtonProps.Loading让 OK 按钮进入加载态若当前对话框是 ModalModalRef对应属性是Config.ConfirmLoading无论哪种都通过UpdateConfigAsync()通知容器重绘。ConfirmRef的UpdateConfigAsync实现ConfirmRef.cs最终调用ModalService.UpdateConfirmAsync(this)触发OnConfirmUpdateEvent由ComfirmContainer执行StateHasChangedComfirmContainer.razor.cs。这个模式的典型用途是点击 OK 后先展示处理中的加载态异步完成业务示例中的Task.Delay(1000)模拟耗时操作再决定是关闭还是取消关闭。四、ConfirmOptions 常用配置项ConfirmOptions继承自DialogOptionsBaseDialogOptionsBase.cs构造时自带一组默认值ConfirmOptions.cs配置项默认值说明Width416对话框宽度Masktrue是否显示遮罩MaskClosablefalse点击遮罩是否可关闭Confirm 默认不可OkText/CancelText取自LocaleProvider.CurrentLocale.ConfirmOK / 取消按钮文案AutoFocusButtonConfirmAutoFocusButton.Ok打开后自动聚焦的按钮OkTypeButtonType.PrimaryOK 按钮类型Keyboardtrue是否支持 Esc 关闭ZIndex1000层级Centeredfalse是否垂直居中常用成员补充说明ContentOneOfstring, RenderFragment字符串或片段均可IconRenderFragment确认框左上角图标通过ConfirmIconInfo/Success/Error/Warning/None可快捷切换并联动ConfirmType样式类ConfirmOptions.csOkCancel是否显示取消按钮默认 OKCancel 双按钮置false时仅 OKOkButtonProps/CancelButtonProps透传给按钮的ButtonPropsLoading、Type、Danger 等ConfirmButtons完整按钮组合OK、OKCancel、YesNo、YesNoCancel、RetryCancel、AbortRetryIgnore由BuildButtonsDefaultOptions按组合填充默认文案ConfirmOptions.csOnOpen/OnClose/OnOk/OnCancel生命周期回调ConfirmOptionsTResult版本中OnOk/OnCancel携带TResult参数。ModalService还提供了一组快捷方法可创建带图标的确认框Confirm/ConfirmAsync、Info/InfoAsync、Success/SuccessAsync、Error/ErrorAsync、Warning/WarningAsyncModalServiceForConfirm.cs以及全局清理DestroyAllConfirmAsync。五、关闭流程与模板销毁Dispose 与 DestroyOnClose示例模板中重写了Dispose并打印日志注释给出了关键提示If you wantDisposeto take effect every time it is closed in Modal, which created by ModalService, setModalOptions.DestroyOnClose true行为差异如下Confirm 对话框BuildDialogOptions中固定设置了DestroyOnClose trueConfirm.razor.cs因此每次关闭后模板组件都会被销毁Dispose必然执行通过ModalService创建的 Modal默认复用模板实例Dispose不会在每次关闭时触发只有设置ModalOptions.DestroyOnClose true才会在关闭时销毁并触发Dispose。这符合 ant-design 的通用行为约定。关闭的完整链路为用户点击按钮 →HandleOk/HandleCancel先回调模板的OnFeedbackOkAsync/OnFeedbackCancelAsync判断args.Cancel→Close()置Visible false、延时 250ms 后通过OnRemove通知容器移除、触发ConfirmRef.OnClose→TaskCompletionSource.TrySetResult唤醒CreateConfirmAsync的等待方。对应实现见 Confirm.razor.cs 与 Confirm.razor。六、两种创建方式的选型建议场景推荐方式纯提示、简单文案、无需交互逻辑直接用ConfirmOptions 字符串Content配合InfoAsync/SuccessAsync等快捷方法内容含少量交互按钮不需要回传值用RenderFragment作为Content示例OpenComponent在片段内通过保存的ConfirmRef主动CloseAsync()表单校验、异步确认、需要把结果回传给调用方自定义模板组件继承FeedbackComponentTComponentOptions, TResult重写OnFeedbackOkAsync校验并用OkCancelRefWithResult.OnOk(value)回传示例OpenTemplate对应演示代码均可直接在仓库中查看Modal_service_for_confirm.razor 与 ConfirmTemplateDemo.razor同目录下还有 Modal_service_for_modal.razor 与 ModalTemplateDemo.razor 展示 Modal 场景的等价写法可对照阅读。关于 Modal 组件的完整 API 与更多示例可查阅 Modal 文档zh-CN。赞分享UI组件前端【免费下载链接】ant-design-blazorA rich set of enterprise-class UI components based on Ant Design and Blazor.项目地址https://gitcode.com/gh_mirrors/an/ant-design-blazor点击查看免费下载相关推荐Ant Design Blazor Drawer 服务方式创建实战自定义模板、自定义组件与结果回传Ant Design Blazor Drawer 服务方式创建实战自定义模板、自定义组件与结果回传 导读 在 Ant Design Blazor 中 DraUI组件前端Ant Design Blazor 评论组件实战用 Comment 模板化 API 构建自定义回复编辑器Ant Design Blazor 评论组件实战用 Comment 模板化 API 构建自定义回复编辑器 评论组件Comment是 Ant DesignUI组件前端Ant Design Blazor Drawer 服务方式创建DrawerService 与自定义模板实战指南Ant Design Blazor Drawer 服务方式创建DrawerService 与自定义模板实战指南 本文聚焦 Ant Design Blazor前端UI组件设计系统创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

GEO实战指南:让DeepSeek、Qwen、豆包、Kimi主动引用你的内容

GEO实战指南:让DeepSeek、Qwen、豆包、Kimi主动引用你的内容

1. GEO 的本质:从抓取页面到喂给模型答案这两年做内容的人应该都有同感:用户正在悄悄换掉搜索引擎。以前找资料,第一反应是打开搜索框,输入关键词,挑前几条蓝色链接点进去;现在越来越多人直接在 DeepSeek、…

📅 2026/10/12 9:53:10
GEO生成式引擎优化:让大模型引用你的内容的完整实战指南

GEO生成式引擎优化:让大模型引用你的内容的完整实战指南

最近大半年,我明显感觉手里的流量盘子变了。以前用户是“搜一下,点链接”,现在越来越多的人直接问AI——让DeepSeek推荐工具、让Kimi总结行业报告、让豆包给个旅游攻略。搜索引擎的点击率在跌,但大模型回答里的“引用来源”正在成…

📅 2026/10/12 9:53:10
用体外记忆解决大模型失忆:claude-mem 本地记忆增强实战

用体外记忆解决大模型失忆:claude-mem 本地记忆增强实战

做AI工具开发的人应该都有同感:跟对话模型聊天,最烦的一点就是它记不住事。上一轮交代过的背景,这一轮再问它,它一脸茫然。我一开始也忍了,毕竟模型天生无状态,上下文窗口就那么大;后来被逼得实…

📅 2026/10/12 9:53:10
MORE NEWS

更多资讯

📰

缠论原始语料结构化:从1634页杂乱网页到可验证知识图谱

简介:本资源是缠论学习者必备的《教你炒股票108课》张星星注解版PDF合集,面向股票与期货交易初学者、技术分析进阶者及缠论系统研修者,旨在解决原典抽象难懂、逻辑断层、缺乏实操锚点等核心学习痛点。全包仅1个65.05MB高清PDF文件&#xff0c…

📰

AI芯片软硬件协同:有效算力与存储墙的瓶颈解析

提到AI芯片,很多人第一反应是去看规格表上的TOPS数字。我最初也是这么干的,但真正把模型从通用平台搬到AI加速卡上之后,才意识到一个残酷事实:纸面算力只是理论峰值,实际跑出来的性能,可能连一半都不到&…

📰

强化学习入门:MDP与贝尔曼方程从原理到代码实现

1. 为什么MDP是强化学习的“地基”很多刚接触强化学习的朋友,在看完环境搭建和基础概念之后,都会卡在同一个地方:马尔可夫决策过程和贝尔曼方程。这两个词听起来像是数学系研究生的专属,但实际上,它们就是强化学习最底…

📰

SkillSpector扫描LLM项目:高危告警为何总评SAFE?评分机制与应对策略

1. 从一次告警面板的诡异现象说起第一次用 SkillSpector 扫完一个自研的 LLM Agent 项目,结果页面让我愣了好几秒:风险列表里明晃晃挂着三条高危告警,可顶部的总评却是一个绿色的 SAFE。当时第一反应是工具坏了,第二反应是——是不…

📰

PHP刷华为机试全攻略:高频算法模板与在线训练实战指南

说实话,用 PHP 去刷大厂机试,很多人的第一反应是“不太行”。但我自己用 PHP 刷完几百道在线训练题之后,反而觉得这套语言在机试场景下非常顺手:字符串处理是看家本领,关联数组天然就是哈希表,写出来的代码…

📰

移动端相机与多媒体框架:从CameraX到MediaCodec的实战指南

《第12章:相机与多媒体框架》一直是移动端进阶里绕不开的一块硬骨头。很多人平时写界面、接接口、做状态管理都没问题,一到相机和多媒体就发怵,因为这套东西不像业务代码那样“输入输出明确”,它要和硬件传感器打交道,…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬