Skip to content

Commit 9f0d084

Browse files
ArgoZhangAiYuZhenAiZhen
authored
feat(PopConfirmButton): support trigger OnClose event callback when click document (#5889)
* refactor: 增加事件移除代码 * feat: 增加 TriggerCloseCallback 回调方法 * refactor: 增加异常保护 * 修复 Ajax 组件 body 内容错误问题 (#5874) * refactor: 重构代码 * chore: bump version 9.5.11-beta02 --------- Co-Authored-By: AiZhen <[email protected]> Co-Authored-By: Argo Zhang <[email protected]> * refactor: 增加空检查逻辑 * perf: 提高性能 * chore: bump version 9.5.11-beta04 * test: 更新单元测试 * test: 更新单元测试 * test: 更新单元测试 * refactor: 使用 data-bb-close 标签 提高性能 * test: 更新单元测试 * test: 增加 OnClose 单元测试 * test: 增加 TriggerCloseCallback 方法单元测试 * chore: bump version 9.5.11-beta05 * refactor: 移除默认值 * test: 消除警告信息 --------- Co-Authored-By: AiZhen <[email protected]> Co-authored-by: AiZhen <[email protected]>
1 parent 5687352 commit 9f0d084

File tree

9 files changed

+84
-22
lines changed

9 files changed

+84
-22
lines changed

src/BootstrapBlazor/BootstrapBlazor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk.Razor">
22

33
<PropertyGroup>
4-
<Version>9.5.11-beta03</Version>
4+
<Version>9.5.11-beta05</Version>
55
</PropertyGroup>
66

77
<ItemGroup>

src/BootstrapBlazor/Components/Button/PopConfirmButton.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ else
1616
RenderFragment RenderComponent =>
1717
@<DynamicElement TagName="@TagName" OnClick="Show" id="@Id"
1818
class="@ClassString" role="dialog" tabindex="@Tab" data-bb-confirm="@ConfirmString"
19+
data-bb-close="@TriggerCloseString"
1920
data-bs-custom-class="@CustomClassString" data-bs-trigger="@TriggerString" data-bs-placement="@PlacementString">
2021
@if(IsAsyncLoading)
2122
{

src/BootstrapBlazor/Components/Button/PopConfirmButton.razor.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ protected override void OnParametersSet()
6969

7070
private string? ConfirmString => OnBeforeClick != null ? "true" : null;
7171

72+
private string? TriggerCloseString => OnClose != null ? "true" : null;
73+
7274
/// <summary>
7375
/// 显示确认弹窗方法
7476
/// </summary>
@@ -97,7 +99,11 @@ private async Task OnClickConfirm()
9799
IsDisabled = true;
98100
IsAsyncLoading = true;
99101
StateHasChanged();
100-
await Task.Run(() => InvokeAsync(OnConfirm));
102+
103+
if (OnConfirm != null)
104+
{
105+
await Task.Run(() => InvokeAsync(OnConfirm));
106+
}
101107

102108
if (ButtonType == ButtonType.Submit)
103109
{
@@ -112,7 +118,10 @@ private async Task OnClickConfirm()
112118
}
113119
else
114120
{
115-
await OnConfirm();
121+
if (OnConfirm != null)
122+
{
123+
await OnConfirm();
124+
}
116125
if (ButtonType == ButtonType.Submit)
117126
{
118127
await TrySubmit();

src/BootstrapBlazor/Components/Button/PopConfirmButton.razor.js

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const config = {
88
popoverSelector: '.popover-confirm.show'
99
}
1010

11-
export function init(id) {
11+
export function init(id, invoke, closeCallback) {
1212
const el = document.getElementById(id)
1313
if (el == null) {
1414
return
@@ -18,7 +18,9 @@ export function init(id) {
1818

1919
const confirm = {
2020
el,
21-
container: el.querySelector('[data-bb-toggle="confirm"]')
21+
container: el.querySelector('[data-bb-toggle="confirm"]'),
22+
invoke,
23+
closeCallback
2224
}
2325
Data.set(id, confirm)
2426

@@ -79,7 +81,17 @@ export function init(id) {
7981
if (element) {
8082
const popover = bootstrap.Popover.getInstance(element);
8183
if (popover) {
82-
popover.hide()
84+
popover.hide();
85+
86+
const id = element.getAttribute('id');
87+
if (id) {
88+
const com = Data.get(id);
89+
const { invoke, closeCallback } = com;
90+
const trigger = element.getAttribute('data-bb-close') === 'true';
91+
if (invoke && trigger) {
92+
invoke.invokeMethodAsync(closeCallback);
93+
}
94+
}
8395
}
8496
}
8597
})
@@ -135,11 +147,17 @@ export function dispose(id) {
135147
const confirm = Data.get(id)
136148
Data.remove(id)
137149

138-
const { popover } = confirm ?? {};
150+
const { popover, el } = confirm ?? {};
139151
if (popover) {
140152
popover.dispose();
141153
}
142154

155+
if (el) {
156+
EventHandler.off(el, 'show.bs.popover')
157+
EventHandler.off(el, 'inserted.bs.popover')
158+
EventHandler.off(el, 'hide.bs.popover')
159+
}
160+
143161
const { PopConfirmButton } = window.BootstrapBlazor;
144162
PopConfirmButton.dispose(id, () => {
145163
EventHandler.off(document, 'click', confirm.closeConfirm)

src/BootstrapBlazor/Components/Button/PopConfirmButtonBase.cs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace BootstrapBlazor.Components;
88
/// <summary>
99
/// 确认弹窗按钮组件
1010
/// </summary>
11-
[BootstrapModuleAutoLoader("Button/PopConfirmButton.razor.js")]
11+
[BootstrapModuleAutoLoader("Button/PopConfirmButton.razor.js", JSObjectReference = true)]
1212
public abstract class PopConfirmButtonBase : ButtonBase
1313
{
1414
/// <summary>
@@ -57,7 +57,6 @@ public abstract class PopConfirmButtonBase : ButtonBase
5757
/// 获得/设置 点击确认时回调方法
5858
/// </summary>
5959
[Parameter]
60-
[NotNull]
6160
public Func<Task>? OnConfirm { get; set; }
6261

6362
/// <summary>
@@ -70,7 +69,6 @@ public abstract class PopConfirmButtonBase : ButtonBase
7069
/// 获得/设置 点击关闭时回调方法
7170
/// </summary>
7271
[Parameter]
73-
[NotNull]
7472
public Func<Task>? OnClose { get; set; }
7573

7674
/// <summary>
@@ -160,12 +158,28 @@ protected override void OnParametersSet()
160158
ConfirmIcon ??= IconTheme.GetIconByKey(ComponentIcons.PopConfirmButtonConfirmIcon);
161159
Trigger ??= "click";
162160

163-
OnClose ??= () => Task.CompletedTask;
164-
OnConfirm ??= () => Task.CompletedTask;
165-
166161
if (Placement != Placement.Top && Placement != Placement.Right && Placement != Placement.Bottom && Placement != Placement.Left)
167162
{
168163
Placement = Placement.Auto;
169164
}
170165
}
166+
167+
/// <summary>
168+
/// <inheritdoc/>
169+
/// </summary>
170+
/// <returns></returns>
171+
protected override Task InvokeInitAsync() => InvokeVoidAsync("init", Id, Interop, nameof(TriggerCloseCallback));
172+
173+
/// <summary>
174+
/// Trigger OnClose event callback.
175+
/// </summary>
176+
/// <returns></returns>
177+
[JSInvokable]
178+
public async Task TriggerCloseCallback()
179+
{
180+
if (OnClose != null)
181+
{
182+
await OnClose();
183+
}
184+
}
171185
}

src/BootstrapBlazor/Components/Table/TableExtensionButton.razor.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ await OnClickButton(new TableCellButtonArgs()
6161

6262
private async Task OnClickConfirm(TableCellPopConfirmButton b)
6363
{
64-
await b.OnConfirm();
64+
if (b.OnConfirm != null)
65+
{
66+
await b.OnConfirm();
67+
}
6568

6669
if (OnClickButton != null)
6770
{

src/BootstrapBlazor/Components/Table/TableToolbar.razor.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,10 @@ private async Task OnConfirm(TableToolbarPopConfirmButton<TItem> button)
9191
await button.OnClick.InvokeAsync();
9292
}
9393

94-
await button.OnConfirm();
94+
if (button.OnConfirm != null)
95+
{
96+
await button.OnConfirm();
97+
}
9598

9699
// 传递当前选中行给回调委托方法
97100
if (button.OnConfirmCallback != null)

test/UnitTest/Components/PopConfirmButtonTest.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public async Task Show_Ok()
2929

3030
cut.Contains("fa-solid fa-xmark");
3131
cut.Contains("fa-solid fa-check");
32+
cut.DoesNotContain("data-bb-close=\"true\"");
3233

3334
// Show
3435
var button = cut.Find("div");
@@ -84,9 +85,14 @@ await cut.InvokeAsync(() =>
8485
return Task.FromResult(true);
8586
});
8687
});
88+
cut.Contains("data-bb-close=\"true\"");
8789
// 默认设置增加 shadow 样式
8890
Assert.Contains("data-bs-custom-class=\"test-custom-class shadow\"", cut.Markup);
8991

92+
close = false;
93+
await cut.InvokeAsync(() => popButton.Instance.TriggerCloseCallback());
94+
Assert.True(close);
95+
9096
// 移除 shadow 样式
9197
popButton.SetParametersAndRender(pb =>
9298
{
@@ -102,6 +108,7 @@ await cut.InvokeAsync(() =>
102108
});
103109

104110
// Close
111+
close = false;
105112
buttons = cut.FindAll(".popover-confirm-buttons button");
106113
await cut.InvokeAsync(() =>
107114
{

test/UnitTest/Components/TableTest.cs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2360,6 +2360,7 @@ public async Task CustomerToolbarPopConfirmButton_Ok()
23602360
{
23612361
var clicked = false;
23622362
var clickCallback = false;
2363+
var confirmCallback = false;
23632364
var localizer = Context.Services.GetRequiredService<IStringLocalizer<Foo>>();
23642365
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
23652366
{
@@ -2390,15 +2391,21 @@ public async Task CustomerToolbarPopConfirmButton_Ok()
23902391
clickCallback = true;
23912392
return Task.CompletedTask;
23922393
}));
2394+
builder.AddAttribute(4, nameof(TableToolbarPopConfirmButton<Foo>.OnConfirm), new Func<Task>(() =>
2395+
{
2396+
confirmCallback = true;
2397+
return Task.CompletedTask;
2398+
}));
23932399
builder.CloseComponent();
23942400
});
23952401
});
23962402
});
23972403

23982404
var button = cut.FindComponent<PopConfirmButton>();
2399-
await cut.InvokeAsync(() => button.Instance.OnConfirm.Invoke());
2405+
await cut.InvokeAsync(() => button.Instance.OnConfirm!.Invoke());
24002406
Assert.True(clickCallback);
24012407
Assert.True(clicked);
2408+
Assert.True(confirmCallback);
24022409
}
24032410

24042411
[Fact]
@@ -5370,7 +5377,7 @@ public async Task Delete_Ok()
53705377
await cut.InvokeAsync(input.Instance.OnToggleClick);
53715378

53725379
var button = cut.FindComponent<TableToolbarPopConfirmButton<Foo>>();
5373-
await cut.InvokeAsync(() => button.Instance.OnConfirm.Invoke());
5380+
await cut.InvokeAsync(() => button.Instance.OnConfirm!.Invoke());
53745381
Assert.Single(items);
53755382
}
53765383

@@ -5420,7 +5427,7 @@ public async Task OnDeleteAsync_Ok()
54205427
await cut.InvokeAsync(input.Instance.OnToggleClick);
54215428

54225429
var button = cut.FindComponent<TableToolbarPopConfirmButton<Foo>>();
5423-
await cut.InvokeAsync(() => button.Instance.OnConfirm.Invoke());
5430+
await cut.InvokeAsync(() => button.Instance.OnConfirm!.Invoke());
54245431

54255432
var row = cut.FindAll("tbody tr");
54265433
Assert.Single(row);
@@ -6199,7 +6206,7 @@ public async Task DynamicContext_Add()
61996206
await cut.InvokeAsync(() => table.Instance.AddAsync());
62006207

62016208
var delete = cut.FindComponent<TableToolbarPopConfirmButton<DynamicObject>>();
6202-
await cut.InvokeAsync(() => delete.Instance.OnConfirm());
6209+
await cut.InvokeAsync(() => delete.Instance.OnConfirm!.Invoke());
62036210
}
62046211

62056212
[Fact]
@@ -6953,13 +6960,13 @@ public void OnConfirm_Ok()
69536960
// 选一个
69546961
var input = cut.FindComponents<Checkbox<Foo>>()[1];
69556962
cut.InvokeAsync(input.Instance.OnToggleClick);
6956-
cut.InvokeAsync(() => deleteButton.Instance.OnConfirm());
6963+
cut.InvokeAsync(() => deleteButton.Instance.OnConfirm!.Invoke());
69576964

69586965
table.SetParametersAndRender(pb =>
69596966
{
69606967
pb.Add(a => a.PageItemsSource, [1, 2, 4, 8]);
69616968
});
6962-
cut.InvokeAsync(() => deleteButton.Instance.OnConfirm());
6969+
cut.InvokeAsync(() => deleteButton.Instance.OnConfirm!.Invoke());
69636970
}
69646971

69656972
[Fact]
@@ -7084,7 +7091,7 @@ public async Task IsExcel_Ok()
70847091
await cut.InvokeAsync(() => table.Instance.AddAsync());
70857092

70867093
var delete = cut.FindComponent<TableToolbarPopConfirmButton<Foo>>();
7087-
await cut.InvokeAsync(() => delete.Instance.OnConfirm());
7094+
await cut.InvokeAsync(() => delete.Instance.OnConfirm!.Invoke());
70887095
}
70897096

70907097
[Fact]

0 commit comments

Comments
 (0)