Skip to content

Commit 5b19fb2

Browse files
authored
doc(Dialog): update OnCloseingAsync documentation (#7702)
* doc: 更新弹窗示例 * doc(DialogOption): add documentation for OnCloseingAsync * doc: 代码格式化
1 parent 58b2fb5 commit 5b19fb2

3 files changed

Lines changed: 258 additions & 58 deletions

File tree

src/BootstrapBlazor.Server/Components/Samples/DialogServices.razor

Lines changed: 132 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,41 @@
1-
@page "/dialog-service"
1+
@page "/dialog-service"
22
@layout MainLayout
33
@inject IStringLocalizer<DialogServices> Localizer
44

5-
<h3>弹窗服务 <code>DialogService</code></h3>
6-
<h4>组件库内置了弹窗服务</h4>
5+
<h3>@((MarkupString)Localizer["Title"].Value)</h3>
6+
<h4>@Localizer["SubTitle"]</h4>
77

8-
<p class="code-label">1. 服务注入</p>
8+
<p class="code-label">@Localizer["CodeLabel1"]</p>
99

1010
<Pre>[Inject]
1111
[NotNull]
1212
private DialogService? DialogService { get; set; }</Pre>
1313

14-
<p class="code-label">2. 使用服务</p>
15-
<p>调用 <code>DialogService</code> 实例方法 <code>Show</code> 即可</p>
14+
<p class="code-label">@Localizer["CodeLabel2"]</p>
15+
<p>@((MarkupString)Localizer["UseServiceDesc"].Value)</p>
1616

1717
<Pre>DialogService.Show(new DialogOption()
1818
{
1919
Title = "Dialog Title"
2020
})</Pre>
2121

22-
<p class="code-label">3. 设计思路</p>
22+
<p class="code-label">@Localizer["CodeLabel3"]</p>
2323

2424
<ul class="ul-demo">
25-
<li>弹窗服务仅仅负责弹出弹窗,提供 <code>Close</code> 关窗功能</li>
26-
<li>显示内容通过 <code>BodyTemplate</code> 模板或者 <code>Component</code> 自行指定</li>
27-
<li>其他更多参数可参见 <code>DialogOption</code> 类定义 <a href="dialog" target="_blank">[传送门]</a></li>
25+
<li>@((MarkupString)Localizer["DesignTip1"].Value)</li>
26+
<li>@((MarkupString)Localizer["DesignTip2"].Value)</li>
27+
<li>@((MarkupString)Localizer["DesignTip3"].Value)</li>
2828
</ul>
2929

30-
<p class="code-label">4. 常见问题</p>
30+
<p class="code-label">@Localizer["CodeLabel4"]</p>
3131

3232
<div>
33-
<GroupBox Title="弹出模态窗" class="mb-3">
34-
<p>组件库提供了 <code>ShowModal</code> 扩展方法</p>
33+
<GroupBox Title="@Localizer["GroupBoxModalTitle"]" class="mb-3">
34+
<p>@((MarkupString)Localizer["GroupBoxModalDesc"].Value)</p>
3535
<Pre>private async Task OnClick()
3636
{
3737
// 弹出模态框
38+
// Open a modal dialog
3839
var result = await DialogService.ShowModal&lt;ResultDialogDemo&gt;(new ResultDialogOption()
3940
{
4041
Title = "Modal popup with return value",
@@ -46,19 +47,21 @@ private DialogService? DialogService { get; set; }</Pre>
4647
});
4748

4849
// 模态框不关闭时此处代码不执行
50+
// Code here does not run until the modal is closed
4951
// 后续逻辑根据弹窗返回值进行相对应的逻辑处理
52+
// Handle subsequent logic based on the return value of the dialog
5053
ModalDialogLogger.Log($"The return value of the popup window is: {result} The return value of the component is: {DemoValue1}");
5154
}</Pre>
5255

53-
<p>以下是个人想法仅供参考:这种应用思路完全是受 <code>WinForm</code> 这种框架影响导致的,以本例展开讲解</p>
56+
<p>@((MarkupString)Localizer["ModalIdeaIntro"].Value)</p>
5457

55-
<p>这样做的目的是,先弹出一个对话框,然后对话框中显示组件 <code>ResultDialogDemo</code> 业务逻辑在这个组件内完成,然后点击其按钮如 <code>关闭</code> 按钮返回 <b>Cancel</b> 点击 <code>保存</code> 按钮返回 <b>Ok</b>,这种思路完全正确,与 <code>WinForm</code> 一致,后续逻辑根据返回值在分别进行逻辑处理。</p>
58+
<p>@((MarkupString)Localizer["ModalIdeaP1"].Value)</p>
5659

57-
<p>我们换个思路,先弹出一个对话框,业务逻辑仍然由 <code>ResultDialogDemo</code> 完成,当点击 <code>关闭</code> 按钮时取消或者回滚业务逻辑操作或者仅关窗,当点击 <code>保存</code> 按钮时对业务处理结果进行入库操作或者其他操作然后关窗,这个思路也是完全没有问题,不需要通过弹窗的返回值进行后续逻辑判断,把业务逻辑处理移到弹窗内显示组件中,个人感觉更加合理代码更加内聚,并且可以解决模态弹窗返回值不够用需要自定义的问题</p>
60+
<p>@((MarkupString)Localizer["ModalIdeaP2"].Value)</p>
5861
</GroupBox>
5962

60-
<GroupBox Title="如何设置模态框的返回值" class="mb-3">
61-
<p>组件库提供了 <code>ShowModal</code> 扩展方法用于弹出模态框,也可以通过调用泛型扩展方法 <code>ShowModal&lt;TDialog&gt;</code> 其组件泛型约束 <code>TDialog</code> 需要继承 <code>IResultDialog</code> 接口,在组件内通过级联参数 <code>SetResultAsync</code> 来设置其模态框返回值,示例代码如下:</p>
63+
<GroupBox Title="@Localizer["GroupBoxSetResultTitle"]" class="mb-3">
64+
<p>@((MarkupString)Localizer["SetResultIntro"].Value)</p>
6265
<Pre>[CascadingParameter(Name = "ResultDialogContext")]
6366
private Func&lt;DialogResult, Task&gt;? SetResultAsync { get; set; }
6467

@@ -69,27 +72,27 @@ private async Task OnClick(DialogResult dialogResult)
6972
await SetResultAsync(dialogResult);
7073
}
7174
}</Pre>
72-
<p>组件内示例代码如下:</p>
75+
<p>@Localizer["SetResultNote"]</p>
7376
<Pre>&lt;DialogCloseButton Color="@@ButtonNoColor" Icon="@@ButtonNoIcon" Text="@@ButtonNoText" OnClickWithoutRender="() => OnClick(DialogResult.No)" /></Pre>
74-
<p>通过以上代码实现点击按钮关闭当前弹窗,并且设置弹窗返回值为 <code>DialogResult.No</code></p>
75-
<p>本组件库内置了 <code>ResultDialogFooter</code> 组件,可以使用或者下载源码学习</p>
77+
<p>@((MarkupString)Localizer["SetResultNote2"].Value)</p>
78+
<p>@((MarkupString)Localizer["SetResultNote3"].Value)</p>
7679
</GroupBox>
7780

78-
<GroupBox Title="代码中如何关闭弹窗" class="mb-3">
79-
<p>在使用弹窗的过程中基本都是需要根据自己的业务需求放置一些业务逻辑处理按钮的,比如放置 <b>关闭</b> <b>保存</b> <b>应用</b> 等等,这些按钮逻辑有些是需要处理业务逻辑结束后,根据业务逻辑处理结果决定是否关闭弹窗,代码关闭弹窗我们组件库内置了一下几种办法</p>
81+
<GroupBox Title="@Localizer["GroupBoxCloseInCodeTitle"]" class="mb-3">
82+
<p>@((MarkupString)Localizer["CloseInCodeIntro"].Value)</p>
8083

81-
<ul class="ul-demo">
82-
<li>弹窗关闭按钮 <code>DialogCloseButton</code></li>
83-
<p>这个组件时专门为弹窗设计的按钮组件,此组件内置了关闭所在弹窗功能,无需任何代码</p>
84+
<ul class="ul-demo mb-0">
85+
<li>@((MarkupString)Localizer["CloseInCodeLi1"].Value)</li>
86+
<p>@Localizer["CloseInCodeLi1Desc"]</p>
8487
<Pre>&lt;DialogCloseButton&gt;</Pre>
85-
<p>业务逻辑可使用 <code>OnClick</code> 或者 <code>OnClickWithoutRender</code> 处理,结束后自动关闭弹窗</p>
86-
<li>关闭回调方法</li>
88+
<p>@((MarkupString)Localizer["CloseInCodeLi1Desc2"].Value)</p>
89+
<li>@Localizer["CloseInCodeLi2"]</li>
8790
<Pre class="mt-3">[CascadingParameter]
8891
private Func&lt;Task&gt;? OnCloseAsync { get; set; }</Pre>
89-
<p>弹窗内部任何组件中均可以通过此级联参数获得一个关闭弹窗的方法,可以根据自己的业务逻辑需求自行调用关闭弹窗</p>
90-
<p><b>注意:</b>级联参数定义可以随意不一定是 <code>OnCloseAsync</code> 也可以根据自己需要更改为 <code>CloseDialogAsync</code></p>
91-
<li>Modal 实例</li>
92-
<p>通过级联参数获得当前 <code>Modal</code> 弹窗实例,然后调用其实例 <code>Close</code> 方法即可关闭当前弹窗</p>
92+
<p>@Localizer["CloseInCodeLi2Desc"]</p>
93+
<p>@((MarkupString)Localizer["CloseInCodeLi2Note"].Value)</p>
94+
<li>@Localizer["CloseInCodeLi3"]</li>
95+
<p>@((MarkupString)Localizer["CloseInCodeLi3Desc"].Value)</p>
9396
<Pre>[CascadingParameter]
9497
[NotNull]
9598
private Modal? Modal { get; set; }
@@ -98,7 +101,78 @@ private Task CloseDialogAsync() => Modal.Close()</Pre>
98101
</ul>
99102
</GroupBox>
100103

101-
<GroupBox Title="不显示弹窗默认按钮" class="mb-3">
104+
<GroupBox Title="@Localizer["GroupBoxInterceptCloseTitle"]" class="mb-3">
105+
<p>@((MarkupString)Localizer["InterceptCloseIntro"].Value)</p>
106+
<ul class="ul-demo mb-0">
107+
<li>@((MarkupString)Localizer["InterceptCloseLi1"].Value)</li>
108+
<Pre class="mt-3">/// &lt;summary&gt;
109+
/// &lt;para lang="zh"&gt;关闭之前回调方法 返回 true 时关闭弹窗 返回 false 时阻止关闭弹窗&lt;/para&gt;
110+
/// &lt;para lang="en"&gt;Callback Method Before Closing. Return true to close, false to prevent closing&lt;/para&gt;
111+
/// &lt;/summary&gt;
112+
Func&lt;Task&lt;bool&gt;&gt;? OnClosingAsync { get; set; }</Pre>
113+
<p>@((MarkupString)Localizer["InterceptCloseLi1Desc"].Value)</p>
114+
<li>@((MarkupString)Localizer["InterceptCloseLi2"].Value)</li>
115+
<p class="mt-3">@((MarkupString)Localizer["InterceptCloseLi2Desc"].Value)</p>
116+
<Pre Height="1082px">[CascadingParameter]
117+
private Modal? Modal { get; set; }
118+
119+
protected override void OnInitialized()
120+
{
121+
base.OnInitialized();
122+
123+
// 通过 Modal 实例方法 RegisterOnClosingCallback 注册关闭回调方法
124+
// Register the closing callback via Modal.RegisterOnClosingCallback
125+
Modal?.RegisterOnClosingCallback(OnClosingCallback);
126+
}
127+
128+
private async Task&lt;bool&gt; OnClosingCallback()
129+
{
130+
var ret = true;
131+
132+
// 根据自己的业务逻辑分析是否有更改 _hasFieldValueChanged 表示编辑表单是否有属性被更改
133+
// Check whether the form has changes; _hasFieldValueChanged indicates if any form field was modified
134+
// 可以通过 ValidateForm 组件的参数 OnFieldValueChanged 在回调中设置 _hasFieldValueChanged 的值
135+
// Set _hasFieldValueChanged in the OnFieldValueChanged callback of ValidateForm
136+
if (_hasFieldValueChanged)
137+
{
138+
var op = new SwalOption()
139+
{
140+
Title = "请注意",
141+
Content = "表单已经更改,确定要关闭么?",
142+
Category = SwalCategory.Question
143+
};
144+
ret = await SwalService.ShowModal(op);
145+
}
146+
147+
// 业务逻辑处理后返回 true 关闭弹窗 返回 false 阻止关闭弹窗
148+
// Return true to close the dialog, false to prevent closing
149+
return ret;
150+
}
151+
152+
private void OnFieldValueChanged(string fieldName, object? value)
153+
{
154+
// fieldName 当前更改的属性名称 value 当前更改的属性值 根据自己的业务逻辑分析是否有更改
155+
// fieldName: name of the changed property; value: new value; set _hasFieldValueChanged per your logic
156+
_hasFieldValueChanged = true;
157+
}
158+
159+
private void Dispose(bool disposing)
160+
{
161+
if (disposing)
162+
{
163+
// 通过 Modal 实例方法 UnRegisterOnClosingCallback 注销关闭回调方法
164+
// Unregister the closing callback via Modal.UnRegisterOnClosingCallback
165+
Modal?.UnRegisterOnClosingCallback(OnClosingCallback);
166+
}
167+
}</Pre>
168+
169+
<p>@((MarkupString)Localizer["ValidateFormTip"].Value)</p>
170+
171+
<Pre>&lt;ValidateForm Model="Model" OnFieldValueChanged="OnFieldValueChanged" OnValidSubmit="OnValidSubmit"&gt;&lt;/ValidateForm&gt;</Pre>
172+
</ul>
173+
</GroupBox>
174+
175+
<GroupBox Title="@Localizer["GroupBoxNoFooterTitle"]" class="mb-3">
102176
<Pre>private async Task OnClickShowDataById()
103177
{
104178
var op = new DialogOption
@@ -111,39 +185,39 @@ private Task CloseDialogAsync() => Modal.Close()</Pre>
111185
await DialogService.Show(op);
112186
}</Pre>
113187

114-
<p>通过设置 <code>ShowFooter="false"</code> 关闭默认按钮,在自定义组件 <code>DataDialogComponent</code> 内自己实现按钮接管业务逻辑,详细代码请在代码仓库中搜索 <b>DataDialogComponent.razor</b></p>
115-
<ul class="ul-demo">
116-
<li>关闭按钮 <code>DialogCloseButton</code></li>
117-
<p>点击后直接关窗,不进行业务逻辑处理</p>
118-
<li>保存按钮 <code>DialogSaveButton</code></li>
119-
<p>点击后触发 <b>Table</b> 组件内置的保存逻辑,此按钮实际为 <code>submit</code> 按钮,提交表单后触发表单验证逻辑,通过数据有效性验证后调用表格组件 <code>OnSaveAsync</code> 回调方法,控制权再次转移到开发者</p>
188+
<p>@((MarkupString)Localizer["NoFooterDesc"].Value)</p>
189+
<ul class="ul-demo mb-0">
190+
<li>@((MarkupString)Localizer["NoFooterLi1"].Value)</li>
191+
<p>@Localizer["NoFooterLi1Desc"]</p>
192+
<li>@((MarkupString)Localizer["NoFooterLi2"].Value)</li>
193+
<p>@((MarkupString)Localizer["NoFooterLi2Desc"].Value)</p>
120194
</ul>
121195
</GroupBox>
122196

123-
<GroupBox Title="组件库内置扩展方法" class="mb-3">
124-
<p>组件库为了方便大家使用 <code>DialogService</code> 内置了一些弹窗扩展方法,稍后继续完善文档</p>
125-
<ul class="ul-demo">
126-
<li>模态框 <code>ShowModal</code></li>
127-
<p>更多参数信息请查看 <code>ResultDialogOption</code></p>
128-
<li>搜索框 <code>ShowSearchDialog</code></li>
129-
<p>更多参数信息请查看 <code>SearchDialogOption</code></p>
130-
<li>编辑框 <code>ShowEditDialog</code></li>
131-
<p>更多参数信息请查看 <code>EditDialogOption</code></p>
132-
<li>保存框 <code>ShowSaveDialog</code></li>
133-
<p>更多参数信息请查看 <code>DialogServiceExtensions</code> 扩展类</p>
134-
<li>关闭框 <code>ShowCloseDialog</code></li>
135-
<p>更多参数信息请查看 <code>DialogServiceExtensions</code> 扩展类</p>
136-
<li>验证表单框 <code>ShowValidateFormDialog</code></li>
137-
<p>更多参数信息请查看 <code>DialogServiceExtensions</code> 扩展类</p>
197+
<GroupBox Title="@Localizer["GroupBoxExtensionsTitle"]" class="mb-3">
198+
<p>@((MarkupString)Localizer["ExtensionsIntro"].Value)</p>
199+
<ul class="ul-demo mb-0">
200+
<li>@((MarkupString)Localizer["ExtensionsLi1"].Value)</li>
201+
<p>@((MarkupString)Localizer["ExtensionsLi1Desc"].Value)</p>
202+
<li>@((MarkupString)Localizer["ExtensionsLi2"].Value)</li>
203+
<p>@((MarkupString)Localizer["ExtensionsLi2Desc"].Value)</p>
204+
<li>@((MarkupString)Localizer["ExtensionsLi3"].Value)</li>
205+
<p>@((MarkupString)Localizer["ExtensionsLi3Desc"].Value)</p>
206+
<li>@((MarkupString)Localizer["ExtensionsLi4"].Value)</li>
207+
<p>@((MarkupString)Localizer["ExtensionsLi4Desc"].Value)</p>
208+
<li>@((MarkupString)Localizer["ExtensionsLi5"].Value)</li>
209+
<p>@((MarkupString)Localizer["ExtensionsLi5Desc"].Value)</p>
210+
<li>@((MarkupString)Localizer["ExtensionsLi6"].Value)</li>
211+
<div>@((MarkupString)Localizer["ExtensionsLi6Desc"].Value)</div>
138212
</ul>
139213
</GroupBox>
140214

141-
<GroupBox Title="Table 组件的编辑弹窗如何增加自定义按钮" class="mb-3">
142-
<p><code>Table</code> 组件有一个 <code>EditFooterTemplate</code> 参数,这是 <code>Dialog</code> 弹窗的 <b>Footer</b> 模板,通过此模板重新设置自己的按钮,实现自定义功能</p>
215+
<GroupBox Title="@Localizer["GroupBoxTableEditFooterTitle"]" class="mb-3">
216+
<p>@((MarkupString)Localizer["TableEditFooterDesc"].Value)</p>
143217
</GroupBox>
144218

145-
<GroupBox Title="Table 组件的编辑弹窗如何获得 ValidateForm 表单实例" class="mb-3">
146-
<p>通过级联参数获得当前表单实例,可调用其实例 <code>Validate</code> 方法进行表单验证</p>
219+
<GroupBox Title="@Localizer["GroupBoxValidateFormTitle"]">
220+
<p>@((MarkupString)Localizer["ValidateFormInstanceDesc"].Value)</p>
147221
<Pre>[CascadingParameter]
148222
private ValidateForm? ValidateForm { get; set; }</Pre>
149223
</GroupBox>

0 commit comments

Comments
 (0)