Skip to content

Commit 3167b47

Browse files
authored
feat(TabItem): Implement IHandlerException interface (#6148)
* refactor: 更改参数值 * feat: 增加 HandlerException 实现逻辑 * test: 补充单元测试 * feat: 增加全局配置参数 * test: 更新单元测试 * test: 增加 TabItemContent 单元测试
1 parent 2df033c commit 3167b47

File tree

4 files changed

+78
-4
lines changed

4 files changed

+78
-4
lines changed

src/BootstrapBlazor/Components/Layout/Layout.razor

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@
148148
RefreshToolbarTooltipText="@RefreshToolbarTooltipText" FullscreenToolbarTooltipText="@FullscreenToolbarTooltipText"
149149
OnToolbarRefreshCallback="OnToolbarRefreshCallback" TabHeader="TabHeader"
150150
Body="@Main" NotAuthorized="NotAuthorized!" NotFound="NotFound!" NotFoundTabText="@NotFoundTabText"
151-
EnableErrorLogger="EnableErrorLogger" ShowErrorLoggerToast="ShowErrorLoggerToast"
151+
EnableErrorLogger="@_enableErrorLogger" ShowErrorLoggerToast="@_showToast"
152152
ErrorLoggerToastTitle="@ErrorLoggerToastTitle">
153153
</Tab>;
154154

src/BootstrapBlazor/Components/Tab/TabItemContent.cs

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace BootstrapBlazor.Components;
99

10-
class TabItemContent : IComponent
10+
class TabItemContent : IComponent, IHandlerException, IDisposable
1111
{
1212
/// <summary>
1313
/// Gets or sets the component content. Default is null
@@ -18,6 +18,15 @@ class TabItemContent : IComponent
1818
[CascadingParameter, NotNull]
1919
private Tab? TabSet { get; set; }
2020

21+
[Inject, NotNull]
22+
private DialogService? DialogService { get; set; }
23+
24+
[Inject]
25+
[NotNull]
26+
private IOptionsMonitor<BootstrapBlazorOptions>? Options { get; set; }
27+
28+
private ErrorLogger? _logger;
29+
2130
private RenderHandle _renderHandle;
2231

2332
void IComponent.Attach(RenderHandle renderHandle)
@@ -55,11 +64,17 @@ private RenderFragment RenderItemContent(RenderFragment? content) => builder =>
5564
builder.OpenComponent<ErrorLogger>(0);
5665
builder.AddAttribute(1, nameof(ErrorLogger.ChildContent), content);
5766

58-
var enableErrorLogger = TabSet.EnableErrorLogger;
59-
var showToast = TabSet.ShowErrorLoggerToast;
67+
var enableErrorLogger = TabSet.EnableErrorLogger ?? Options.CurrentValue.EnableErrorLogger;
68+
var showToast = TabSet.ShowErrorLoggerToast ?? Options.CurrentValue.ShowErrorLoggerToast;
6069
builder.AddAttribute(2, nameof(ErrorLogger.EnableErrorLogger), enableErrorLogger);
6170
builder.AddAttribute(3, nameof(ErrorLogger.ShowToast), showToast);
6271
builder.AddAttribute(4, nameof(ErrorLogger.ToastTitle), TabSet.ErrorLoggerToastTitle);
72+
builder.AddAttribute(5, nameof(ErrorLogger.OnInitializedCallback), new Func<ErrorLogger, Task>(logger =>
73+
{
74+
_logger = logger;
75+
_logger.Register(this);
76+
return Task.CompletedTask;
77+
}));
6378
builder.CloseComponent();
6479
};
6580

@@ -75,4 +90,20 @@ public void Render()
7590
_key = new object();
7691
RenderContent();
7792
}
93+
94+
/// <summary>
95+
/// HandlerException 错误处理方法
96+
/// </summary>
97+
/// <param name="ex"></param>
98+
/// <param name="errorContent"></param>
99+
public Task HandlerException(Exception ex, RenderFragment<Exception> errorContent) => DialogService.ShowErrorHandlerDialog(errorContent(ex));
100+
101+
/// <summary>
102+
/// IDispose 方法用于释放资源
103+
/// </summary>
104+
public void Dispose()
105+
{
106+
_logger?.UnRegister(this);
107+
GC.SuppressFinalize(this);
108+
}
78109
}

test/UnitTest/Components/ErrorLoggerTest.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,46 @@ public void ErrorContent_Ok()
185185
cut.InvokeAsync(() => button.Click());
186186
cut.Contains("Attempted to divide by zero.error_content_template");
187187
}
188+
189+
[Fact]
190+
public async Task TabItem_Error()
191+
{
192+
var cut = Context.RenderComponent<BootstrapBlazorRoot>(pb =>
193+
{
194+
pb.AddChildContent<Tab>(pb =>
195+
{
196+
pb.AddChildContent<TabItem>(pb =>
197+
{
198+
pb.Add(a => a.Text, "Text1");
199+
pb.Add(a => a.ChildContent, builder => builder.AddContent(0, RenderButton()));
200+
});
201+
});
202+
});
203+
204+
var button = cut.Find("button");
205+
await cut.InvokeAsync(() => button.Click());
206+
207+
// 页面不崩溃,由弹窗显示异常信息
208+
cut.Contains("<div class=\"error-stack\">TimeStamp:");
209+
210+
// 单元测试覆盖 TabItemContent Dispose 方法
211+
var handler = Activator.CreateInstance("BootstrapBlazor", "BootstrapBlazor.Components.TabItemContent");
212+
Assert.NotNull(handler);
213+
var content = handler.Unwrap();
214+
Assert.NotNull(content);
215+
216+
Assert.IsType<IDisposable>(content, exactMatch: false);
217+
((IDisposable)content).Dispose();
218+
}
219+
220+
private RenderFragment RenderButton() => builder =>
221+
{
222+
builder.OpenComponent<Button>(0);
223+
builder.AddAttribute(2, nameof(Button.OnClick), EventCallback.Factory.Create<MouseEventArgs>(this, e =>
224+
{
225+
var a = 0;
226+
_ = 1 / a;
227+
}));
228+
builder.CloseComponent();
229+
};
188230
}

test/UnitTest/Components/ImageTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ public void IsIntersectionObserver_Ok()
128128
{
129129
var cut = Context.RenderComponent<ImageViewer>(pb =>
130130
{
131+
pb.Add(a => a.ZoomSpeed, 0.5d);
131132
pb.Add(a => a.Url, "https://www.blazor.zone/images/logo.png");
132133
pb.Add(a => a.IsIntersectionObserver, true);
133134
});

0 commit comments

Comments
 (0)